convert download view to modal

This commit is contained in:
Andrew Bauer 2020-09-30 09:12:54 -05:00
parent 3eae356ed7
commit 2d30d7aafa
7 changed files with 165 additions and 243 deletions

View File

@ -0,0 +1,119 @@
<?php
// This is the HTML representing the Download event modal on the Events page and other pages
function getDLEventHTML($eid, $eids) {
$result = '';
if ( !empty($eid) ) {
$result .= '<input type="hidden" name="id" value="' .validInt($eid). '"/>'.PHP_EOL;
$Event = new ZM\Event($eid);
if ( !$Event->Id() ) {
ZM\Error('Invalid event id');
$result .= '<div class="error">Invalid event id</div>'.PHP_EOL;
} else {
$result .= 'Downloading event ' . $Event->Id . '. Resulting file should be approximately ' . human_filesize( $Event->DiskSpace() ).PHP_EOL;
}
} else if ( !empty($eids) ) {
$total_size = 0;
foreach ( $eids as $eid ) {
if ( !validInt($eid) ) {
ZM\Warning("Invalid event id in eids[] $eid");
continue;
}
$Event = new ZM\Event($eid);
$total_size += $Event->DiskSpace();
$result .= '<input type="hidden" name="eids[]" value="' .validInt($eid). '"/>'.PHP_EOL;
}
unset($eid);
$result .= 'Downloading ' . count($eids) . ' events. Resulting file should be approximately ' . human_filesize($total_size).PHP_EOL;
} else {
$result .= '<div class="warning">There are no events found. Resulting download will be empty.</div>';
}
return $result;
}
if ( !canView('Events') ) {
$view = 'error';
return;
}
$eid = isset($_REQUEST['eid']) ? $_REQUEST['eid'] : '';
$eids = isset($_REQUEST['eids']) ? $_REQUEST['eids'] : array();
$generated = isset($_REQUEST['generated']) ? $_REQUEST['generated'] : '';
$total_size = 0;
if ( isset($_SESSION['montageReviewFilter']) and !$eids ) {
# Handles montageReview filter
$eventsSql = 'SELECT E.Id, E.DiskSpace FROM Events AS E WHERE 1';
$eventsSql .= $_SESSION['montageReviewFilter']['sql'];
$results = dbQuery($eventsSql);
while ( $event_row = dbFetchNext( $results ) ) {
array_push($eids, $event_row['Id']);
$total_size += $event_row['DiskSpace'];
}
if ( ! count($eids) ) {
ZM\Error("No events found for download using $eventsSql");
}
#session_start();
#unset($_SESSION['montageReviewFilter']);
#session_write_close();
#} else {
#Logger::Debug("NO montageReviewFilter");
}
$exportFormat = '';
if ( isset($_REQUEST['exportFormat']) ) {
if ( !in_array($_REQUEST['exportFormat'], array('zip', 'tar')) ) {
ZM\Error('Invalid exportFormat: '.$_REQUEST['exportFormat']);
} else {
$exportFormat = $_REQUEST['exportFormat'];
}
}
$focusWindow = true;
$connkey = isset($_REQUEST['connkey']) ? validInt($_REQUEST['connkey']) : generateConnKey();
?>
<div id="downloadModal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><?php echo translate('Download') ?></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form name="contentForm" id="downloadForm" method="post" action="?">
<?php
// We have to manually insert the csrf key into the form when using a modal generated via ajax call
echo getCSRFinputHTML();
?>
<input type="hidden" name="connkey" value="<?php echo $connkey; ?>"/>
<input type="hidden" name="exportVideo" value="1"/>
<div>
<?php echo getDLEventHTML($eid, $eids) ?>
</div>
<div class="font-weight-bold py-2">
<span class="pr-3"><?php echo translate('ExportFormat') ?></span>
<input type="radio" id="exportFormatTar" name="exportFormat" value="tar"/>
<label for="exportFormatTar"><?php echo translate('ExportFormatTar') ?></label>
<input type="radio" id="exportFormatZip" name="exportFormat" value="zip" checked="checked"/>
<label for="exportFormatZip"><?php echo translate('ExportFormatZip') ?></label>
</div>
<button type="button" id="exportButton" name="exportButton" value="GenerateDownload"><?php echo translate('GenerateDownload') ?></button>
</form>
</div>
<h2 id="exportProgress" class="text-warning invisible">
<span class="spinner-grow" role="status" aria-hidden="true"></span>
Exporting...
</h2>
<h3><a id="downloadLink" href="#"></a></h3>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>

View File

@ -924,4 +924,34 @@ function human_filesize(size, precision = 2) {
return (Math.round(size*(10^precision))/(10^precision))+units[i];
}
function startDownload( exportFile ) {
console.log("Starting download from " + exportFile);
window.location.replace( exportFile );
}
function exportResponse(data, responseText) {
console.log(data);
var generated = (data.result=='Ok') ? 1 : 0;
var exportFile = '?view=archive&type='+data.exportFormat+'&connkey='+data.connkey;
$j('#exportProgress').removeClass( 'text-warning' );
if ( generated ) {
$j('#downloadLink').text('Download');
$j('#downloadLink').attr("href", thisUrl + exportFile);
$j('#exportProgress').addClass( 'text-success' );
$j('#exportProgress').text(exportSucceededString);
startDownload.pass( exportFile ).delay( 1500 );
} else {
$j('#exportProgress').addClass( 'text-danger' );
$j('#exportProgress').text(exportFailedString);
}
}
function exportEvent() {
var form = $j('#downloadForm').serialize();
$j.getJSON(thisUrl + '?view=request&request=event&action=download', form)
.done(exportResponse)
.fail(logAjaxFail);
$j('#exportProgress').removeClass( 'invisible' );
}

View File

@ -25,10 +25,12 @@
?>
var AJAX_TIMEOUT = <?php echo ZM_WEB_AJAX_TIMEOUT ?>;
var navBarRefresh = <?php echo 1000*ZM_WEB_REFRESH_NAVBAR ?>;
var currentView = '<?php echo $view ?>';
var exportProgressString = '<?php echo addslashes(translate('Exporting')) ?>';
var exportFailedString = '<?php echo translate('ExportFailed') ?>';
var exportSucceededString = '<?php echo translate('ExportSucceeded') ?>';
<?php
/* We can't trust PHP_SELF on a path like /index.php/"%3E%3Cimg src=x onerror=prompt('1');%3E which
will still load index.php but will include the arbitrary payload after `.php/`. To mitigate this,

View File

@ -1,154 +0,0 @@
<?php
//
// ZoneMinder web export view file, $Date$, $Revision$
// Copyright (C) 2001-2008 Philip Coombes
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
function getDLEventHTML($eid, $eids) {
$result = '';
if ( !empty($eid) ) {
$result .= '<input type="hidden" name="id" value="' .validInt($eid). '"/>'.PHP_EOL;
$Event = new ZM\Event($eid);
if ( !$Event->Id() ) {
ZM\Error('Invalid event id');
$result .= '<div class="error">Invalid event id</div>'.PHP_EOL;
} else {
$result .= 'Downloading event ' . $Event->Id . '. Resulting file should be approximately ' . human_filesize( $Event->DiskSpace() ).PHP_EOL;
}
} else if ( !empty($eids) ) {
$total_size = 0;
foreach ( $eids as $eid ) {
if ( !validInt($eid) ) {
ZM\Warning("Invalid event id in eids[] $eid");
continue;
}
$Event = new ZM\Event($eid);
$total_size += $Event->DiskSpace();
$result .= '<input type="hidden" name="eids[]" value="' .validInt($eid). '"/>'.PHP_EOL;
}
unset($eid);
$result .= 'Downloading ' . count($eids) . ' events. Resulting file should be approximately ' . human_filesize($total_size).PHP_EOL;
} else {
$result .= '<div class="warning">There are no events found. Resulting download will be empty.</div>';
}
return $result;
}
function getGeneratedHTML($generated, $exportFormat) {
$result = '';
if ( $generated == '' ) {
$result .= '<h2 id="exportProgress" class="hidden warnText">'.PHP_EOL;
$result .= '<span id="exportProgressText">' .translate('Exporting'). '</span>'.PHP_EOL;
$result .= '<span id="exportProgressTicker"></span>'.PHP_EOL;
$result .= '</h2>'.PHP_EOL;
} else {
$result .= '<h2 id="exportProgress" class="' .($generated ? 'infoText' : 'errorText').'">'.PHP_EOL;
$result .= '<span id="exportProgressText">' .($generated ? translate('ExportSucceeded') : translate('ExportFailed')). '</span>'.PHP_EOL;
$result .= '<span id="exportProgressTicker"></span>'.PHP_EOL;
$result .= '</h2>'.PHP_EOL;
}
if ( $generated ) {
$result .= '<h3 id="downloadLink"><a href="?view=archive&amp;type=' .$exportFormat. '">' .translate('Download'). '</a></h3>'.PHP_EOL;
}
return $result;
}
if ( !canView('Events') ) {
$view = 'error';
return;
}
$eid = isset($_REQUEST['eid']) ? $_REQUEST['eid'] : '';
$eids = isset($_REQUEST['eids']) ? $_REQUEST['eids'] : array();
$generated = isset($_REQUEST['generated']) ? $_REQUEST['generated'] : '';
$total_size = 0;
if ( isset($_SESSION['montageReviewFilter']) and !$eids ) {
# Handles montageReview filter
$eventsSql = 'SELECT E.Id, E.DiskSpace FROM Events AS E WHERE 1';
$eventsSql .= $_SESSION['montageReviewFilter']['sql'];
$results = dbQuery($eventsSql);
while ( $event_row = dbFetchNext( $results ) ) {
array_push($eids, $event_row['Id']);
$total_size += $event_row['DiskSpace'];
}
if ( ! count($eids) ) {
ZM\Error("No events found for download using $eventsSql");
}
#session_start();
#unset($_SESSION['montageReviewFilter']);
#session_write_close();
#} else {
#Logger::Debug("NO montageReviewFilter");
}
$exportFormat = '';
if ( isset($_REQUEST['exportFormat']) ) {
if ( !in_array($_REQUEST['exportFormat'], array('zip', 'tar')) ) {
ZM\Error('Invalid exportFormat: '.$_REQUEST['exportFormat']);
} else {
$exportFormat = $_REQUEST['exportFormat'];
}
}
$focusWindow = true;
$connkey = isset($_REQUEST['connkey']) ? validInt($_REQUEST['connkey']) : generateConnKey();
xhtmlHeaders(__FILE__, translate('Download'));
?>
<body>
<div id="page">
<div id="header">
<div id="headerButtons">
<a href="#" data-on-click="closeWindow"><?php echo translate('Close') ?></a>
</div>
<h2><?php echo translate('Download') ?></h2>
</div>
<div id="content">
<form name="contentForm" id="contentForm" method="post" action="?">
<input type="hidden" name="connkey" value="<?php echo $connkey; ?>"/>
<?php echo getDLEventHTML($eid, $eids) ?>
<table id="contentTable" class="minor">
<tbody>
<tr>
<td><input type="hidden" name="exportVideo" value="1"/></td>
</tr>
<tr>
<th scope="row"><?php echo translate('ExportFormat') ?></th>
<td>
<input type="radio" id="exportFormatTar" name="exportFormat" value="tar"/>
<label for="exportFormatTar"><?php echo translate('ExportFormatTar') ?></label>
<input type="radio" id="exportFormatZip" name="exportFormat" value="zip" checked="checked"/>
<label for="exportFormatZip"><?php echo translate('ExportFormatZip') ?></label>
</td>
</tr>
</tbody>
</table>
<button type="button" id="exportButton" name="exportButton" value="GenerateDownload">
<!--data-on-click-this="exportEvent">-->
<?php echo translate('GenerateDownload') ?>
</button>
</form>
</div>
<?php echo getGeneratedHTML($generated, $exportFormat) ?>
</div>
<?php xhtmlFooter() ?>

View File

@ -1,63 +0,0 @@
function configureExportButton( element ) {
var form = element.form;
var radioCount = 0;
for ( var i = 0, len=form.elements.length; i < len; i++ ) {
if ( form.elements[i].type == "radio" && form.elements[i].checked ) {
radioCount++;
}
}
form.elements['exportButton'].disabled = (radioCount == 0);
}
function startDownload( exportFile ) {
console.log("Starting download from " + exportFile);
window.location.replace( exportFile );
}
var exportTimer = null;
function exportProgress() {
var tickerText = $j('#exportProgressTicker').text();
if ( tickerText.length < 1 || tickerText.length > 4 ) {
$j('#exportProgressTicker').text( '.' );
} else {
$j('#exportProgressTicker').append( '.' );
}
}
function exportResponse(respObj, respText) {
console.log(respObj);
var fullUrl = thisUrl+'?view='+currentView+'&'+eidParm+
'&exportFormat='+respObj.exportFormat+
'&exportFile='+respObj.exportFile+
'&generated='+((respObj.result=='Ok')?1:0)+
'&connkey='+connkey;
console.log('The full url is: ' + fullUrl);
window.location.replace(fullUrl);
}
function exportEvent() {
var form = $j('#contentForm').serialize();
$j.getJSON(thisUrl + '?view=request&request=event&action=download', form)
.done(exportResponse)
.fail(logAjaxFail);
$j('#exportProgress').removeClass( 'hidden' );
$j('#exportProgress').addClass( 'warnText' );
$j('#exportProgressText').text( exportProgressString );
exportProgress();
exportTimer = exportProgress.periodical( 500 );
}
function initPage() {
if ( exportReady ) {
startDownload.pass( exportFile ).delay( 1500 );
}
document.getElementById('exportButton').addEventListener("click", exportEvent );
}
$j(document).ready(function() {
initPage();
});

View File

@ -1,23 +0,0 @@
<?php
global $connkey;
global $exportFormat;
if ( isset($_REQUEST['eids']) ) {
$eidParms = array();
foreach ( $_REQUEST['eids'] as $eid )
$eidParms[] = 'eids[]='.validInt($eid);
?>
var eidParm = '<?php echo join('&', $eidParms) ?>';
<?php
} else if (isset($_REQUEST['eid'])) {
?>
var eidParm = 'eid=<?php echo validInt($_REQUEST['eid']) ?>';
<?php
}
?>
var exportReady = <?php echo !empty($_REQUEST['generated'])?'true':'false' ?>;
var exportFile = '?view=archive&type=<?php echo $exportFormat; ?>&connkey=<?php echo $connkey; ?>';
var connkey = '<?php echo $connkey ?>';
var exportProgressString = '<?php echo addslashes(translate('Exporting')) ?>';

View File

@ -240,7 +240,18 @@ function initPage() {
var selections = getIdSelections();
evt.preventDefault();
createPopup('?view=download&eids[]='+selections.join('&eids[]='), 'zmDownload', 'download');
$j.getJSON(thisUrl + '?request=modal&modal=download&eids[]='+selections.join('&eids[]='))
.done(function(data) {
if ( $j('#downloadModal').length ) {
$j('#downloadModal').replaceWith(data.html);
} else {
$j("body").append(data.html);
}
$j('#downloadModal').modal('show');
// Manage the GENERATE DOWNLOAD button
$j('#exportButton').click(exportEvent);
})
.fail(logAjaxFail);
});
// Manage the DELETE button