From c87d170972604ff7b825a38001fcb86b32f379fe Mon Sep 17 00:00:00 2001
From: digital-gnome <31593470+digital-gnome@users.noreply.github.com>
Date: Sat, 9 Dec 2017 11:23:22 -0500
Subject: [PATCH 01/40] Pass montagereview filter
---
web/skins/classic/views/montagereview.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/web/skins/classic/views/montagereview.php b/web/skins/classic/views/montagereview.php
index cbb1e59b7..8476ce426 100644
--- a/web/skins/classic/views/montagereview.php
+++ b/web/skins/classic/views/montagereview.php
@@ -87,6 +87,7 @@ if (isset($_REQUEST['minTime']) && isset($_REQUEST['maxTime']) && count($display
$_SESSION['montageReviewFilter'] = $filter;
session_write_close();
}
+$filterQuery = $filter['query'];
// Note that this finds incomplete events as well, and any frame records written, but still cannot "see" to the end frame
// if the bulk record has not been written - to be able to include more current frames reduce bulk frame sizes (event size can be large)
From ee5552d9f9f96af3689b8eaee8a343e3ef9af590 Mon Sep 17 00:00:00 2001
From: digital-gnome <31593470+digital-gnome@users.noreply.github.com>
Date: Sat, 9 Dec 2017 11:23:50 -0500
Subject: [PATCH 02/40] Redirect Events when post
Fixes broken back due to form resubmit
---
web/skins/classic/views/events.php | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/web/skins/classic/views/events.php b/web/skins/classic/views/events.php
index 3d426191b..0ec975d53 100644
--- a/web/skins/classic/views/events.php
+++ b/web/skins/classic/views/events.php
@@ -88,6 +88,11 @@ $pagination = getPagination( $pages, $page, $maxShortcuts, $filterQuery.$sortQue
$focusWindow = true;
+if ($_POST) {
+ header("Location: " . $_SERVER['REQUEST_URI'].htmlspecialchars_decode($filterQuery).htmlspecialchars_decode($sortQuery).'&limit='.$limit.'&page='.$page);
+ exit();
+}
+
xhtmlHeaders(__FILE__, translate('Events') );
?>
From 9eb03a881d6a596fddcc68ff12204bed27b50b52 Mon Sep 17 00:00:00 2001
From: digital-gnome <31593470+digital-gnome@users.noreply.github.com>
Date: Sat, 9 Dec 2017 22:13:17 -0500
Subject: [PATCH 03/40] Always have a full line on filter page.
This allows javascript to copy easily
---
web/skins/classic/views/filter.php | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/web/skins/classic/views/filter.php b/web/skins/classic/views/filter.php
index a180fd242..4f0e8c0a9 100644
--- a/web/skins/classic/views/filter.php
+++ b/web/skins/classic/views/filter.php
@@ -54,7 +54,12 @@ $conjunctionTypes = array(
$obracketTypes = array();
$cbracketTypes = array();
-$terms = $filter->terms();
+if (count($filter->terms()) > 0) {
+ $terms = $filter->terms();
+} else {
+ $terms[] = array();
+}
+
if ( count($terms) ) {
for ( $i = 0; $i <= count($terms)-2; $i++ ) {
$obracketTypes[$i] = str_repeat( '(', $i );
@@ -293,13 +298,6 @@ for ( $i=0; $i < count($terms); $i++ ) {
?>
-
-
-
From 8515e77d67e5abc8bc023592dacfdd79c240551a Mon Sep 17 00:00:00 2001
From: digital-gnome <31593470+digital-gnome@users.noreply.github.com>
Date: Sat, 9 Dec 2017 22:15:27 -0500
Subject: [PATCH 04/40] Add text type to text fields
---
web/skins/classic/views/filter.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/web/skins/classic/views/filter.php b/web/skins/classic/views/filter.php
index 4f0e8c0a9..b545b0e1c 100644
--- a/web/skins/classic/views/filter.php
+++ b/web/skins/classic/views/filter.php
@@ -209,7 +209,7 @@ for ( $i=0; $i < count($terms); $i++ ) {
?>
|
-
+
@@ -272,13 +272,13 @@ for ( $i=0; $i < count($terms); $i++ ) {
} else {
?>
| |
- |
+ |
|
- |
+ |
From fe6a6bec7ce9cee28c7a4338bcdf4eec565ef89f Mon Sep 17 00:00:00 2001
From: digital-gnome <31593470+digital-gnome@users.noreply.github.com>
Date: Sat, 9 Dec 2017 22:16:52 -0500
Subject: [PATCH 05/40] Use disabled button rather than remove
Reduces page jumping
---
web/skins/classic/views/filter.php | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/web/skins/classic/views/filter.php b/web/skins/classic/views/filter.php
index b545b0e1c..ebaa173be 100644
--- a/web/skins/classic/views/filter.php
+++ b/web/skins/classic/views/filter.php
@@ -284,14 +284,9 @@ for ( $i=0; $i < count($terms); $i++ ) {
?>
2 ) { echo htmlSelect( "filter[Query][terms][$i][cbr]", $cbracketTypes, $term['cbr'] ); } else { ?> |
-
- 1 ) {
-?>
-
- |
+
+ />
+
Date: Sat, 9 Dec 2017 22:17:54 -0500
Subject: [PATCH 06/40] Change reset to not reload form
---
web/skins/classic/views/filter.php | 2 +-
web/skins/classic/views/js/filter.js | 5 +++++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/web/skins/classic/views/filter.php b/web/skins/classic/views/filter.php
index ebaa173be..01775134e 100644
--- a/web/skins/classic/views/filter.php
+++ b/web/skins/classic/views/filter.php
@@ -413,7 +413,7 @@ if ( canEdit( 'Events' ) ) {
}
}
?>
-
+
diff --git a/web/skins/classic/views/js/filter.js b/web/skins/classic/views/js/filter.js
index 31746c0f9..6902159cc 100644
--- a/web/skins/classic/views/js/filter.js
+++ b/web/skins/classic/views/js/filter.js
@@ -46,6 +46,11 @@ function submitToFilter( element ) {
form.submit();
}
+function resetFilter( element ) {
+ element.form.reset();
+ $j('#contentForm')[0].reset();
+}
+
function submitToEvents( element ) {
var form = element.form;
if ( validateForm( form ) ) {
From d5ec45eed77decb8178f2a88c2db81737fb18049 Mon Sep 17 00:00:00 2001
From: digital-gnome <31593470+digital-gnome@users.noreply.github.com>
Date: Sat, 9 Dec 2017 22:19:01 -0500
Subject: [PATCH 07/40] Include all DateTime possibilities
---
web/skins/classic/views/filter.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/web/skins/classic/views/filter.php b/web/skins/classic/views/filter.php
index 01775134e..be4fa0a2a 100644
--- a/web/skins/classic/views/filter.php
+++ b/web/skins/classic/views/filter.php
@@ -205,7 +205,7 @@ for ( $i=0; $i < count($terms); $i++ ) {
|
|
|
From 51b4ddb0e4ed4dc50bed7ac84f98dab2f8bcbc4d Mon Sep 17 00:00:00 2001
From: digital-gnome <31593470+digital-gnome@users.noreply.github.com>
Date: Sat, 9 Dec 2017 22:20:35 -0500
Subject: [PATCH 08/40] Add js for filter handling
---
web/skins/classic/views/filter.php | 2 +-
web/skins/classic/views/js/filter.js | 103 +++++++++++++++++++++------
2 files changed, 84 insertions(+), 21 deletions(-)
diff --git a/web/skins/classic/views/filter.php b/web/skins/classic/views/filter.php
index be4fa0a2a..9816ac6b8 100644
--- a/web/skins/classic/views/filter.php
+++ b/web/skins/classic/views/filter.php
@@ -197,7 +197,7 @@ for ( $i=0; $i < count($terms); $i++ ) {
}
?>
| 2 ) { echo htmlSelect( "filter[Query][terms][$i][obr]", $obracketTypes, $term['obr'] ); } else { ?> |
- |
+ |
0 && i > 0 && inputs[0].children.length == 0) { //add and/or to 1+ if doesn't exist
+ $j(inputs[0]).html('');
+ }
+ let brackets = rows.length - 2;
+ if (brackets > 0) { //add bracket td to all rows
+ let obr = '';
+ let obrVal = $j(inputs[1]).children().val(); //Save currently selected bracket option
+ let cbrVal = $j(inputs[5]).children().val();
+ $j(inputs[1]).html(obr).children().val(obrVal); //Set bracket contents and assign saved value
+ $j(inputs[5]).html(cbr).children().val(cbrVal);
+ } else {
+ $j(inputs[1]).html(' ');
+ $j(inputs[5]).html(' ');
+ }
+ if ($j(inputs[2]).children().val() == "Archived") { //Archived filter is very different. Handles html changes.
+ $j(inputs[3]).html('equal to');
+ $j(inputs[4]).html('');
+ } else if ($j(inputs[3]).children().attr('type') == 'hidden' ) {
+ $j(inputs[3]).html('');
+ $j(inputs[4]).html('');
+ }
+ for (let j = 0; j < inputs.length; j++) { //Set all query array values in case any were missed
+ let input = inputs[j].children;
+ if (input.length) { //Ignore placeholders.
+ if (input[0].type == 'button' && rows.length == 1) { //if add/delete button disable when only term
+ $j(input[1]).prop('disabled', true);
+ } else if (input[0].type == 'button') { //Enable if more than one term
+ $j(input[1]).prop('disabled', false);
+ } else { // Set all non-button array values
+ let term = input[0].name.split(/[[\]]{1,2}/);
+ term.length--;
+ term.shift();
+ term[2] = i;
+ input[0].name = 'filter'+stringFilter(term);
+ input[0].id = 'filter'+stringFilter(term);
+ }
+ }
+ }
+ }
}
-function delTerm( element, line ) {
- var form = element.form;
- form.target = window.name;
- form.action = thisUrl + '?view='+currentView;
- form.elements['object'].value = 'filter';
- form.elements['action'].value = 'delterm';
- form.elements['line'].value = line;
- form.submit();
+function stringFilter (term) {
+ let termString = '';
+ term.forEach(function(item) {
+ termString += '[' + item + ']';
+ });
+ return termString;
+}
+
+function addTerm( element ) {
+ let row = $j(element).closest('tr');
+ let newRow = row.clone().insertAfter(row);
+ newRow.find('select').each( function () { //reset new row to default
+ this[0].selected = 'selected';
+ });
+ newRow.find('input[type="text"]').val('');
+ let rows = $j(row).parent().children();
+ parseRows(rows);
+}
+
+function delTerm( element ) {
+ let row = $j(element).closest('tr');
+ let rowParent = $j(row).parent();
+ row.remove();
+ let rows = rowParent.children();
+ parseRows(rows);
}
function init() {
From c1cf356974ddbae3f7446d1b1f9f3e4b786fe3a6 Mon Sep 17 00:00:00 2001
From: digital-gnome <31593470+digital-gnome@users.noreply.github.com>
Date: Sun, 10 Dec 2017 12:57:47 -0500
Subject: [PATCH 09/40] Montagereview filter passing in wrong block
---
web/skins/classic/views/montagereview.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/web/skins/classic/views/montagereview.php b/web/skins/classic/views/montagereview.php
index 8476ce426..0a81f46dd 100644
--- a/web/skins/classic/views/montagereview.php
+++ b/web/skins/classic/views/montagereview.php
@@ -86,8 +86,8 @@ if (isset($_REQUEST['minTime']) && isset($_REQUEST['maxTime']) && count($display
session_start();
$_SESSION['montageReviewFilter'] = $filter;
session_write_close();
+ $filterQuery = $filter['query'];
}
-$filterQuery = $filter['query'];
// Note that this finds incomplete events as well, and any frame records written, but still cannot "see" to the end frame
// if the bulk record has not been written - to be able to include more current frames reduce bulk frame sizes (event size can be large)
From c936e9e2a9dad59214ce502a32ae8bb68f99334c Mon Sep 17 00:00:00 2001
From: digital-gnome <31593470+digital-gnome@users.noreply.github.com>
Date: Sun, 10 Dec 2017 12:58:08 -0500
Subject: [PATCH 10/40] No longer need line
---
web/skins/classic/views/filter.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/web/skins/classic/views/filter.php b/web/skins/classic/views/filter.php
index 9816ac6b8..95dd140ce 100644
--- a/web/skins/classic/views/filter.php
+++ b/web/skins/classic/views/filter.php
@@ -155,7 +155,6 @@ if ( (null !== $filter->Concurrent()) and $filter->Concurrent() )
From a6b136ed406edf9a45c580c507cc2d4983a26bb2 Mon Sep 17 00:00:00 2001
From: digital-gnome <31593470+digital-gnome@users.noreply.github.com>
Date: Mon, 18 Dec 2017 09:18:36 -0500
Subject: [PATCH 34/40] dark theme fixes
Overrides bootstrap input colors for dark theme and more chosen
---
web/skins/classic/css/dark/skin.css | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/web/skins/classic/css/dark/skin.css b/web/skins/classic/css/dark/skin.css
index 251bfc30c..4ef70091d 100644
--- a/web/skins/classic/css/dark/skin.css
+++ b/web/skins/classic/css/dark/skin.css
@@ -90,14 +90,14 @@ label {
}
input,textarea,select,button,.btn-primary {
- border: 1px #8f8fc2 solid;
+ border: 1px #8f8fc2 solid !important;
padding: 10px;
border-radius: 2px;
font-family: inherit;
font-weight: 400;
font-size: 100%;
- color: #eeeeee;
- background-color: #444444;
+ color: #eeeeee !important;
+ background-color: #444444 !important;
}
input[type=text], input[type=password], input[type="url"], textarea, select {
@@ -560,7 +560,14 @@ input[type=submit]:disabled,
}
/* Override chosen for dark theme */
-.chosen-single, .chosen-container {
+.chosen-single,
+.chosen-container,
+.chosen-container-multi,
+.chosen-results,
+.chosen-search,
+.chosen-drop,
+.chosen-choices,
+li.search-choice {
font-size: inherit !important;
background: -webkit-gradient(linear,left top,left bottom,color-stop(20%,#555),color-stop(50%,#464646),color-stop(52%,#444),to(#545454)) !important;
background: linear-gradient(#555 20%,#464646 50%,#444 52%,#545454 100%) !important;
@@ -568,12 +575,7 @@ input[type=submit]:disabled,
color: #eee !important;
border-color: #8f8fc2 !important;
-webkit-box-shadow: none !important;
-
-}
-
-.chosen-results, .chosen-search, .chosen-drop, .chosen-choices {
- color: #eee !important;
- background-color: #444444 !important;
+ background-image: none !important;
}
/* end chosen override */
From d312482a2bacb972003fe58cc4f318c818407d8d Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Mon, 18 Dec 2017 12:52:26 -0500
Subject: [PATCH 35/40] add StorageScheme to Storage and Events. Deprecate
ZM_USE_DEEP_STORAGE
---
db/zm_create.sql.in | 1 +
db/zm_update-1.31.17.sql | 28 ++++++++++++++
scripts/ZoneMinder/lib/ZoneMinder/Event.pm | 37 +++++++++++++------
scripts/zmaudit.pl.in | 11 +++++-
src/zm_event.cpp | 41 +++++++++++++--------
src/zm_storage.cpp | 26 +++++++++++--
src/zm_storage.h | 16 ++++++--
version | 2 +-
web/ajax/status.php | 1 -
web/api/app/Controller/EventsController.php | 4 +-
web/includes/Event.php | 8 ++--
web/includes/Frame.php | 28 --------------
web/includes/functions.php | 8 ----
web/skins/classic/views/storage.php | 15 ++++++--
14 files changed, 146 insertions(+), 80 deletions(-)
create mode 100644 db/zm_update-1.31.17.sql
diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in
index ec035d227..5d15ca59b 100644
--- a/db/zm_create.sql.in
+++ b/db/zm_create.sql.in
@@ -639,6 +639,7 @@ CREATE TABLE `Storage` (
`Name` varchar(64) NOT NULL default '',
`Type` enum('local','s3fs') NOT NULL default 'local',
`DiskSpace` bigint unsigned default NULL,
+ `Scheme enum('Deep','Medium','Shallow') NOT NULL default 'Medium',
PRIMARY KEY (`Id`)
) ENGINE=@ZM_MYSQL_ENGINE@;
diff --git a/db/zm_update-1.31.17.sql b/db/zm_update-1.31.17.sql
new file mode 100644
index 000000000..3177eaaeb
--- /dev/null
+++ b/db/zm_update-1.31.17.sql
@@ -0,0 +1,28 @@
+alter table Events modify Id int(10) unsigned;
+alter table Events DROP Primary key;
+alter table Events Add Primary key(Id);
+alter table Events modify Id int(10) unsigned auto_incremement;
+
+SET @s = (SELECT IF(
+ (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
+ AND table_name = 'Storage'
+ AND column_name = 'Scheme'
+ ) > 0,
+ "SELECT 'Column Scheme already exists in Storage'",
+ "ALTER TABLE Storage ADD `Scheme enum('Deep','Medium','Shallow') NOT NULL default 'Medium' AFTER `DiskSpace`"
+ ));
+
+PREPARE stmt FROM @s;
+EXECUTE stmt;
+
+SET @s = (SELECT IF(
+ (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
+ AND table_name = 'Events'
+ AND column_name = 'StorageScheme'
+ ) > 0,
+ "SELECT 'Column StorageScheme already exists in Events'",
+ "ALTER TABLE Events ADD `StorageScheme enum('Deep','Medium','Shallow') NOT NULL default 'Deep' AFTER `DiskSpace`"
+ ));
+
+PREPARE stmt FROM @s;
+EXECUTE stmt;
diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm
index 7f0dc6575..fc8698f15 100644
--- a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm
+++ b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm
@@ -154,13 +154,14 @@ sub Path {
if ( ! $$event{Path} ) {
my $Storage = $event->Storage();
+
- if ( $Config{ZM_USE_DEEP_STORAGE} ) {
+ if ( $$events{Scheme} eq 'Deep' ) {
if ( $event->Time() ) {
$$event{Path} = join('/',
$Storage->Path(),
$event->{MonitorId},
- strftime( "%y/%m/%d/%H/%M/%S",
+ strftime( '%y/%m/%d/%H/%M/%S',
localtime($event->Time())
),
);
@@ -168,7 +169,18 @@ sub Path {
Error("Event $$event{Id} has no value for Time(), unable to determine path");
$$event{Path} = '';
}
- } else {
+ } elsif ( $$events{Scheme} eq 'Medium' ) {
+ if ( $event->Time() ) {
+ $$event{Path} = join('/',
+ $Storage->Path(),
+ $event->{MonitorId},
+ strftime( '%y-%m-%d', localtime($event->Time())),
+ $event->{Id},
+ );
+ } else {
+ Error("Event $$event{Id} has no value for Time(), unable to determine path");
+ $$event{Path} = '';
+ } else { # Shallow
$$event{Path} = join('/',
$Storage->Path(),
$event->{MonitorId},
@@ -307,24 +319,25 @@ sub delete {
} # end sub delete
sub delete_files {
+ my $event = shift;
- my $Storage = @_ > 1 ? $_[1] : new ZoneMinder::Storage( $_[0]{StorageId} );
+ my $Storage = @_ ? $_[0] : new ZoneMinder::Storage( $$event{StorageId} );
my $storage_path = $Storage->Path();
if ( ! $storage_path ) {
- Fatal("Empty storage path when deleting files for event $_[0]{Id} with storage id $_[0]{StorageId} ");
+ Fatal("Empty storage path when deleting files for event $$event{Id} with storage id $$event{StorageId} ");
return;
}
chdir( $storage_path );
- if ( $Config{ZM_USE_DEEP_STORAGE} ) {
- if ( ! $_[0]{MonitorId} ) {
- Error("No monitor id assigned to event $_[0]{Id}");
+ if ( $$event{Scheme} eq 'Deep' ) {
+ if ( ! $$event{MonitorId} ) {
+ Error("No monitor id assigned to event $$event{Id}");
return;
}
- Debug("Deleting files for Event $_[0]{Id} from $storage_path.");
- my $link_path = $_[0]{MonitorId}."/*/*/*/.".$_[0]{Id};
+ Debug("Deleting files for Event $$event{Id} from $storage_path.");
+ my $link_path = $$event{MonitorId}."/*/*/*/.".$$event{Id};
#Debug( "LP1:$link_path" );
my @links = glob($link_path);
#Debug( "L:".$links[0].": $!" );
@@ -356,9 +369,9 @@ sub delete_files {
my $command = "/bin/rm -rf $storage_path/$delete_path";
ZoneMinder::General::executeShellCommand( $command );
}
- }
+ } # end if links
} else {
- my $command = "/bin/rm -rf $storage_path/$_[0]{MonitorId}/$_[0]{Id}";
+ my $command = "/bin/rm -rf ". $event->Path();
ZoneMinder::General::executeShellCommand( $command );
}
} # end sub delete_files
diff --git a/scripts/zmaudit.pl.in b/scripts/zmaudit.pl.in
index 1593777b4..2de067c3e 100644
--- a/scripts/zmaudit.pl.in
+++ b/scripts/zmaudit.pl.in
@@ -191,7 +191,7 @@ MAIN: while( $loop ) {
# De-taint
( my $monitor_dir ) = ( $monitor =~ /^(.*)$/ );
- if ( $Config{ZM_USE_DEEP_STORAGE} ) {
+ if ( $$Storage{Scheme} eq 'Deep' ) {
foreach my $day_dir ( glob("$monitor_dir/*/*/*") ) {
Debug( "Checking day dir $day_dir" );
( $day_dir ) = ( $day_dir =~ /^(.*)$/ ); # De-taint
@@ -235,6 +235,15 @@ MAIN: while( $loop ) {
} # end foreach event_link
chdir( $Storage->Path() );
} # end foreach day dir
+ } elsif ( $$Storage{Scheme} eq 'Medium' ) {
+ foreach my $event_dir ( glob("$monitor_dir/*/*") ) {
+ next if ! -d $event_dir;
+ my $Event = $fs_events->{$event} = new ZoneMinder::Event();
+ $$Event{Id} = $event;
+ $$Event{Path} = $event_dir;
+ $Event->MonitorId( $monitor_dir );
+ $Event->StorageId( $Storage->Id() );
+ } # end foreach event
} else {
if ( ! chdir( $monitor_dir ) ) {
Error( "Can't chdir directory '$$Storage{Path}/$monitor_dir': $!" );
diff --git a/src/zm_event.cpp b/src/zm_event.cpp
index b86c2f18f..6d4a411de 100644
--- a/src/zm_event.cpp
+++ b/src/zm_event.cpp
@@ -71,7 +71,7 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string
static char sql[ZM_SQL_MED_BUFSIZ];
struct tm *stime = localtime( &start_time.tv_sec );
- snprintf( sql, sizeof(sql), "INSERT INTO Events ( MonitorId, StorageId, Name, StartTime, Width, Height, Cause, Notes, StateId, Orientation, Videoed, DefaultVideo, SaveJPEGs ) values ( %d, %d, 'New Event', from_unixtime( %ld ), %d, %d, '%s', '%s', %d, %d, %d, '', %d )",
+ snprintf( sql, sizeof(sql), "INSERT INTO Events ( MonitorId, StorageId, Name, StartTime, Width, Height, Cause, Notes, StateId, Orientation, Videoed, DefaultVideo, SaveJPEGs, StorageScheme ) values ( %d, %d, 'New Event', from_unixtime( %ld ), %d, %d, '%s', '%s', %d, %d, %d, '', %d, '%s' )",
monitor->Id(),
storage->Id(),
start_time.tv_sec,
@@ -82,7 +82,8 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string
state_id,
monitor->getOrientation(),
videoEvent,
- monitor->GetOptSaveJPEGs()
+ monitor->GetOptSaveJPEGs(),
+ storage->SchemeString()
);
if ( mysql_query( &dbconn, sql ) ) {
Error( "Can't insert event: %s. sql was (%s)", mysql_error( &dbconn ), sql );
@@ -101,7 +102,7 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string
struct stat statbuf;
char id_file[PATH_MAX];
- if ( config.use_deep_storage ) {
+ if ( storage->Scheme() == Storage::Schemes::DEEP ) {
char *path_ptr = path;
path_ptr += snprintf( path_ptr, sizeof(path), "%s/%d", storage->Path(), monitor->Id() );
@@ -120,15 +121,10 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string
path_ptr += snprintf( path_ptr, sizeof(path)-(path_ptr-path), "/%02d", dt_parts[i] );
errno = 0;
- // Do we really need to stat it? Perhaps we could do that on error, instead
- if ( stat( path, &statbuf ) ) {
- if ( errno == ENOENT || errno == ENOTDIR ) {
- if ( mkdir( path, 0755 ) ) {
- // FIXME This should not be fatal. Should probably move to a different storage area.
- Fatal( "Can't mkdir %s: %s", path, strerror(errno));
- }
- } else {
- Warning( "Error stat'ing %s, may be fatal. error is %s", path, strerror(errno));
+ if ( mkdir( path, 0755 ) ) {
+ // FIXME This should not be fatal. Should probably move to a different storage area.
+ if ( errno != EEXIST ) {
+ Error( "Can't mkdir %s: %s", path, strerror(errno));
}
}
if ( i == 2 )
@@ -140,11 +136,26 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string
snprintf( id_file, sizeof(id_file), "%s/.%d", date_path, id );
if ( symlink( time_path, id_file ) < 0 )
Error( "Can't symlink %s -> %s: %s", id_file, path, strerror(errno));
+ } else if ( storage->Scheme() == Storage::Schemes::MEDIUM ) {
+ char *path_ptr = path;
+ path_ptr += snprintf( path_ptr, sizeof(path), "%s/%d/%02d-%02d-%02d",
+ storage->Path(), monitor->Id(), stime->tm_year-100, stime->tm_mon+1, stime->tm_mday
+ );
+ if ( mkdir( path, 0755 ) ) {
+ // FIXME This should not be fatal. Should probably move to a different storage area.
+ if ( errno != EEXIST )
+ Error( "Can't mkdir %s: %s", path, strerror(errno));
+ }
+ path_ptr += snprintf( path_ptr, sizeof(path), "/%d", id );
+ if ( mkdir( path, 0755 ) ) {
+ // FIXME This should not be fatal. Should probably move to a different storage area.
+ if ( errno != EEXIST )
+ Error( "Can't mkdir %s: %s", path, strerror(errno));
+ }
} else {
snprintf( path, sizeof(path), "%s/%d/%d", storage->Path(), monitor->Id(), id );
-
- if ( stat( path, &statbuf ) && ( errno == ENOENT || errno == ENOTDIR ) ) {
- if ( mkdir( path, 0755 ) ) {
+ if ( mkdir( path, 0755 ) ) {
+ if ( errno != EEXIST ) {
Error( "Can't mkdir %s: %s", path, strerror(errno));
}
}
diff --git a/src/zm_storage.cpp b/src/zm_storage.cpp
index 0b3857302..042bacc76 100644
--- a/src/zm_storage.cpp
+++ b/src/zm_storage.cpp
@@ -36,6 +36,8 @@ Storage::Storage() {
} else {
strncpy(path, staticConfig.DIR_EVENTS.c_str(), sizeof(path)-1 );
}
+ scheme = Schemes::SHALLOW;
+ scheme_str = "Shallow";
}
Storage::Storage( MYSQL_ROW &dbrow ) {
@@ -43,6 +45,15 @@ Storage::Storage( MYSQL_ROW &dbrow ) {
id = atoi( dbrow[index++] );
strncpy( name, dbrow[index++], sizeof(name)-1 );
strncpy( path, dbrow[index++], sizeof(path)-1 );
+ type_str = std::string(dbrow[index++]);
+ scheme_str = std::string(dbrow[index++]);
+ if ( scheme_str == "Deep" ) {
+ scheme = Schemes::DEEP;
+ } else if ( scheme_str == "Medium" ) {
+ scheme = Schemes::MEDIUM;
+ } else {
+ scheme = Schemes::SHALLOW;
+ }
}
/* If a zero or invalid p_id is passed, then the old default path will be assumed. */
@@ -51,7 +62,7 @@ Storage::Storage( unsigned int p_id ) {
if ( p_id ) {
char sql[ZM_SQL_SML_BUFSIZ];
- snprintf( sql, sizeof(sql), "SELECT Id, Name, Path from Storage WHERE Id=%d", p_id );
+ snprintf( sql, sizeof(sql), "SELECT Id, Name, Path, Type, Scheme from Storage WHERE Id=%d", p_id );
Debug(2,"Loading Storage for %d using %s", p_id, sql );
zmDbRow dbrow;
if ( ! dbrow.fetch( sql ) ) {
@@ -59,8 +70,17 @@ Storage::Storage( unsigned int p_id ) {
} else {
unsigned int index = 0;
id = atoi( dbrow[index++] );
- strncpy( name, dbrow[index++], sizeof(name) );
- strncpy( path, dbrow[index++], sizeof(path) );
+ strncpy( name, dbrow[index++], sizeof(name)-1 );
+ strncpy( path, dbrow[index++], sizeof(path)-1 );
+ type_str = std::string(dbrow[index++]);
+ scheme_str = std::string(dbrow[index++]);
+ if ( scheme_str == "Deep" ) {
+ scheme = Schemes::DEEP;
+ } else if ( scheme_str == "Medium" ) {
+ scheme = Schemes::MEDIUM;
+ } else {
+ scheme = Schemes::SHALLOW;
+ }
Debug( 1, "Loaded Storage area %d '%s'", id, this->Name() );
}
}
diff --git a/src/zm_storage.h b/src/zm_storage.h
index 75817a903..f0886c9f3 100644
--- a/src/zm_storage.h
+++ b/src/zm_storage.h
@@ -24,11 +24,19 @@
class Storage {
public:
+ typedef enum {
+ SHALLOW=0,
+ MEDIUM,
+ DEEP
+ } Schemes;
protected:
unsigned int id;
char name[64+1];
char path[64+1];
+ std::string type_str;
+ std::string scheme_str;
+ Schemes scheme;
public:
Storage();
@@ -36,9 +44,11 @@ public:
explicit Storage( unsigned int p_id );
~Storage();
- unsigned int Id() const { return( id ); }
- const char *Name() const { return( name ); }
- const char *Path() const { return( path ); }
+ unsigned int Id() const { return id; }
+ const char *Name() const { return name; }
+ const char *Path() const { return path; }
+ const Schemes Scheme() const { return scheme; }
+ const std::string SchemeString() const { return scheme_str; }
};
#endif // ZM_STORAGE_H
diff --git a/version b/version
index d1a8f5341..874058d96 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-1.31.16
+1.31.17
diff --git a/web/ajax/status.php b/web/ajax/status.php
index dcd53cc95..2e9977a3d 100644
--- a/web/ajax/status.php
+++ b/web/ajax/status.php
@@ -138,7 +138,6 @@ $statusData = array(
'MaxFrameId' => array( 'sql' => '(SELECT max(Frames.FrameId) FROM Frames WHERE Events.Id = Frames.EventId)' ),
'MinFrameDelta' => array( 'sql' => '(SELECT min(Frames.Delta) FROM Frames WHERE Events.Id = Frames.EventId)' ),
'MaxFrameDelta' => array( 'sql' => '(SELECT max(Frames.Delta) FROM Frames WHERE Events.Id = Frames.EventId)' ),
- //'Path' => array( 'postFunc' => 'getEventPath' ),
),
),
'frames' => array(
diff --git a/web/api/app/Controller/EventsController.php b/web/api/app/Controller/EventsController.php
index 3f3c3c8b4..446285729 100644
--- a/web/api/app/Controller/EventsController.php
+++ b/web/api/app/Controller/EventsController.php
@@ -123,8 +123,8 @@ class EventsController extends AppController {
$options = array('conditions' => array(array('Event.' . $this->Event->primaryKey => $id), $mon_options));
$event = $this->Event->find('first', $options);
- $path = $configs['ZM_DIR_EVENTS'].'/'.$this->Image->getEventPath($event).'/';
- $event['Event']['BasePath'] = $path;
+ //$path = $configs['ZM_DIR_EVENTS'].'/'.$this->Image->getEventPath($event).'/';
+ //$event['Event']['BasePath'] = $path;
# Get the previous and next events for any monitor
$this->Event->id = $id;
diff --git a/web/includes/Event.php b/web/includes/Event.php
index 0c9a15b87..c8dffec92 100644
--- a/web/includes/Event.php
+++ b/web/includes/Event.php
@@ -86,8 +86,10 @@ class Event {
public function Relative_Path() {
$event_path = '';
- if ( ZM_USE_DEEP_STORAGE ) {
+ if ( $this->{'Scheme'} == 'Deep' ) {
$event_path = $this->{'MonitorId'} .'/'.strftime( '%y/%m/%d/%H/%M/%S', $this->Time()) ;
+ } else if ( $this->{'Scheme'} eq 'Medium' ) {
+ $event_path = $this->{'MonitorId'} .'/'.strftime( '%y-%m-%d', $this->Time() ) . '/'.$this->{'Id'};
} else {
$event_path = $this->{'MonitorId'} .'/'.$this->{'Id'};
}
@@ -96,7 +98,7 @@ class Event {
} // end function Relative_Path()
public function Link_Path() {
- if ( ZM_USE_DEEP_STORAGE ) {
+ if ( $this->{'Scheme'} == 'Deep' ) {
return $this->{'MonitorId'} .'/'.strftime( '%y/%m/%d/.', $this->Time()).$this->{'Id'};
}
Error('Calling Link_Path when not using deep storage');
@@ -109,7 +111,7 @@ class Event {
if ( !ZM_OPT_FAST_DELETE ) {
dbQuery( 'DELETE FROM Stats WHERE EventId = ?', array($this->{'Id'}) );
dbQuery( 'DELETE FROM Frames WHERE EventId = ?', array($this->{'Id'}) );
- if ( ZM_USE_DEEP_STORAGE ) {
+ if ( $this->{'Scheme'} == 'Deep' ) {
# Assumption: All events have a start time
$start_date = date_parse( $this->{'StartTime'} );
diff --git a/web/includes/Frame.php b/web/includes/Frame.php
index 7575aeed8..95a949365 100644
--- a/web/includes/Frame.php
+++ b/web/includes/Frame.php
@@ -49,34 +49,6 @@ class Frame {
}
}
- public function Path() {
- $Storage = $this->Storage();
- return $Storage->Path().'/'.$this->Relative_Path();
- }
- public function Relative_Path() {
- $event_path = "";
-
- if ( ZM_USE_DEEP_STORAGE )
- {
- $event_path =
- $this->{'MonitorId'}
- .'/'.strftime( "%y/%m/%d/%H/%M/%S",
- $this->Time()
- )
- ;
- }
- else
- {
- $event_path =
- $this->{'MonitorId'}
- .'/'.$this->{'Id'}
- ;
- }
-
- return( $event_path );
-
- }
-
public function getImageSrc( $show='capture' ) {
return $_SERVER['PHP_SELF'].'?view=image&fid='.$this->{'FrameId'}.'&eid='.$this->{'EventId'}.'&show='.$show;
diff --git a/web/includes/functions.php b/web/includes/functions.php
index 9dfedfbad..0b1d3385b 100644
--- a/web/includes/functions.php
+++ b/web/includes/functions.php
@@ -465,14 +465,6 @@ function canEdit( $area, $mid=false ) {
return( $user[$area] == 'Edit' && ( !$mid || visibleMonitor( $mid ) ) );
}
-function getEventPath( $event ) {
- if ( ZM_USE_DEEP_STORAGE )
- $eventPath = $event['MonitorId'].'/'.strftime( '%y/%m/%d/%H/%M/%S', strtotime($event['StartTime']) );
- else
- $eventPath = $event['MonitorId'].'/'.$event['Id'];
- return( $eventPath );
-}
-
function getEventDefaultVideoPath( $event ) {
$Event = new Event( $event );
return $Event->getStreamSrc( array( 'mode'=>'mpeg', 'format'=>'h264' ) );
diff --git a/web/skins/classic/views/storage.php b/web/skins/classic/views/storage.php
index 067881298..d74ea9079 100644
--- a/web/skins/classic/views/storage.php
+++ b/web/skins/classic/views/storage.php
@@ -33,9 +33,15 @@ if ( $_REQUEST['id'] ) {
$newStorage['Name'] = translate('NewStorage');
$newStorage['Path'] = '';
$newStorage['Type'] = 'local';
+ $newStorage['Scheme'] = 'Medium';
}
$type_options = array( 'local' => translate('Local'), 's3fs' => translate('s3fs') );
+$scheme_options = array(
+ 'Deep' => translate('Deep'),
+ 'Medium' => translate('Medium'),
+ 'Shallow' => translate('Shallow'),
+);
$focusWindow = true;
@@ -65,12 +71,15 @@ xhtmlHeaders(__FILE__, translate('Storage')." - ".$newStorage['Name'] );
|
|
+
+ |
+ |
+
-
-
-
+
+
From c93de992c2117a8021057f25af14d484a4187684 Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Mon, 18 Dec 2017 13:04:57 -0500
Subject: [PATCH 36/40] add Scheme to the list of fields
---
web/includes/Event.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/web/includes/Event.php b/web/includes/Event.php
index c8dffec92..aaf6ae010 100644
--- a/web/includes/Event.php
+++ b/web/includes/Event.php
@@ -10,6 +10,7 @@ class Event {
'Name',
'DiskSpace',
'SaveJPEGs',
+'Scheme',
);
public function __construct( $IdOrRow = null ) {
$row = NULL;
From 0e2d2ce6119e7a549fc67295d5d8d92e8469f026 Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Mon, 18 Dec 2017 13:05:04 -0500
Subject: [PATCH 37/40] fix typos
---
db/zm_update-1.31.17.sql | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/db/zm_update-1.31.17.sql b/db/zm_update-1.31.17.sql
index 3177eaaeb..78d50d153 100644
--- a/db/zm_update-1.31.17.sql
+++ b/db/zm_update-1.31.17.sql
@@ -1,7 +1,7 @@
alter table Events modify Id int(10) unsigned;
alter table Events DROP Primary key;
alter table Events Add Primary key(Id);
-alter table Events modify Id int(10) unsigned auto_incremement;
+alter table Events modify Id int(10) unsigned auto_increment;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
@@ -9,7 +9,7 @@ SET @s = (SELECT IF(
AND column_name = 'Scheme'
) > 0,
"SELECT 'Column Scheme already exists in Storage'",
- "ALTER TABLE Storage ADD `Scheme enum('Deep','Medium','Shallow') NOT NULL default 'Medium' AFTER `DiskSpace`"
+ "ALTER TABLE Storage ADD `Scheme` enum('Deep','Medium','Shallow') NOT NULL default 'Medium' AFTER `DiskSpace`"
));
PREPARE stmt FROM @s;
@@ -18,10 +18,10 @@ EXECUTE stmt;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Events'
- AND column_name = 'StorageScheme'
+ AND column_name = 'Scheme'
) > 0,
- "SELECT 'Column StorageScheme already exists in Events'",
- "ALTER TABLE Events ADD `StorageScheme enum('Deep','Medium','Shallow') NOT NULL default 'Deep' AFTER `DiskSpace`"
+ "SELECT 'Column Scheme already exists in Events'",
+ "ALTER TABLE Events ADD `Scheme` enum('Deep','Medium','Shallow') NOT NULL default 'Deep' AFTER `DiskSpace`"
));
PREPARE stmt FROM @s;
From dcfae11fc7226b9847403688d49c949a7bbe9724 Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Mon, 18 Dec 2017 13:16:54 -0500
Subject: [PATCH 38/40] fix typos
---
scripts/ZoneMinder/lib/ZoneMinder/Event.pm | 10 +++++-----
web/includes/Event.php | 2 +-
web/lang/en_gb.php | 1 +
web/skins/classic/views/options.php | 2 ++
4 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm
index fc8698f15..1abbdb06c 100644
--- a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm
+++ b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm
@@ -155,8 +155,7 @@ sub Path {
if ( ! $$event{Path} ) {
my $Storage = $event->Storage();
-
- if ( $$events{Scheme} eq 'Deep' ) {
+ if ( $$event{Scheme} eq 'Deep' ) {
if ( $event->Time() ) {
$$event{Path} = join('/',
$Storage->Path(),
@@ -169,7 +168,7 @@ sub Path {
Error("Event $$event{Id} has no value for Time(), unable to determine path");
$$event{Path} = '';
}
- } elsif ( $$events{Scheme} eq 'Medium' ) {
+ } elsif ( $$event{Scheme} eq 'Medium' ) {
if ( $event->Time() ) {
$$event{Path} = join('/',
$Storage->Path(),
@@ -180,14 +179,15 @@ sub Path {
} else {
Error("Event $$event{Id} has no value for Time(), unable to determine path");
$$event{Path} = '';
+ }
} else { # Shallow
$$event{Path} = join('/',
$Storage->Path(),
$event->{MonitorId},
$event->{Id},
);
- }
- } # end if
+ } # end if Scheme
+ } # end if ! Path
return $$event{Path};
}
diff --git a/web/includes/Event.php b/web/includes/Event.php
index aaf6ae010..2ba780138 100644
--- a/web/includes/Event.php
+++ b/web/includes/Event.php
@@ -89,7 +89,7 @@ class Event {
if ( $this->{'Scheme'} == 'Deep' ) {
$event_path = $this->{'MonitorId'} .'/'.strftime( '%y/%m/%d/%H/%M/%S', $this->Time()) ;
- } else if ( $this->{'Scheme'} eq 'Medium' ) {
+ } else if ( $this->{'Scheme'} == 'Medium' ) {
$event_path = $this->{'MonitorId'} .'/'.strftime( '%y-%m-%d', $this->Time() ) . '/'.$this->{'Id'};
} else {
$event_path = $this->{'MonitorId'} .'/'.$this->{'Id'};
diff --git a/web/lang/en_gb.php b/web/lang/en_gb.php
index d1e2d09bf..bf65b46a3 100644
--- a/web/lang/en_gb.php
+++ b/web/lang/en_gb.php
@@ -687,6 +687,7 @@ $SLANG = array(
'Stills' => 'Stills',
'Stopped' => 'Stopped',
'Stop' => 'Stop',
+ 'StorageScheme' => 'Scheme',
'StreamReplayBuffer' => 'Stream Replay Image Buffer',
'Stream' => 'Stream',
'Submit' => 'Submit',
diff --git a/web/skins/classic/views/options.php b/web/skins/classic/views/options.php
index 36565f8d6..443fe4337 100644
--- a/web/skins/classic/views/options.php
+++ b/web/skins/classic/views/options.php
@@ -248,6 +248,7 @@ foreach( array_map( 'basename', glob('skins/'.$current_skin.'/css/*',GLOB_ONLYDI
|
|
|
+ |
|
@@ -258,6 +259,7 @@ foreach( array_map( 'basename', glob('skins/'.$current_skin.'/css/*',GLOB_ONLYDI
|
|
|
+ |
disabled="disabled"/> |
From 705a98276f16594b9d4bc5b9bd8b72e8fed6ad4f Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Mon, 18 Dec 2017 13:17:43 -0500
Subject: [PATCH 39/40] change StorageScheme to Scheme
---
src/zm_event.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/zm_event.cpp b/src/zm_event.cpp
index 6d4a411de..cb3f5d702 100644
--- a/src/zm_event.cpp
+++ b/src/zm_event.cpp
@@ -71,7 +71,7 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string
static char sql[ZM_SQL_MED_BUFSIZ];
struct tm *stime = localtime( &start_time.tv_sec );
- snprintf( sql, sizeof(sql), "INSERT INTO Events ( MonitorId, StorageId, Name, StartTime, Width, Height, Cause, Notes, StateId, Orientation, Videoed, DefaultVideo, SaveJPEGs, StorageScheme ) values ( %d, %d, 'New Event', from_unixtime( %ld ), %d, %d, '%s', '%s', %d, %d, %d, '', %d, '%s' )",
+ snprintf( sql, sizeof(sql), "INSERT INTO Events ( MonitorId, StorageId, Name, StartTime, Width, Height, Cause, Notes, StateId, Orientation, Videoed, DefaultVideo, SaveJPEGs, Scheme ) values ( %d, %d, 'New Event', from_unixtime( %ld ), %d, %d, '%s', '%s', %d, %d, %d, '', %d, '%s' )",
monitor->Id(),
storage->Id(),
start_time.tv_sec,
From 8a8001f14a18a51dcb112bb3625e614fab0694f6 Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Mon, 18 Dec 2017 13:25:24 -0500
Subject: [PATCH 40/40] fix missingc_str()
---
src/zm_event.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/zm_event.cpp b/src/zm_event.cpp
index cb3f5d702..31cbba39d 100644
--- a/src/zm_event.cpp
+++ b/src/zm_event.cpp
@@ -83,7 +83,7 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string
monitor->getOrientation(),
videoEvent,
monitor->GetOptSaveJPEGs(),
- storage->SchemeString()
+ storage->SchemeString().c_str()
);
if ( mysql_query( &dbconn, sql ) ) {
Error( "Can't insert event: %s. sql was (%s)", mysql_error( &dbconn ), sql );