if op == 'delete':
self.delete(camera_id, filename)
+ elif op == 'delete_all':
+ self.delete_all(camera_id, group)
+
else:
raise HTTPError(400, 'unknown operation')
width=self.get_argument('width', None),
height=self.get_argument('height', None))
- @BaseHandler.auth()
+ @BaseHandler.auth(admin=True)
def delete(self, camera_id, filename):
logging.debug('deleting picture %(filename)s of camera %(id)s' % {
'filename': filename, 'id': camera_id})
remote.get_timelapse_movie(camera_config, framerate, interval, callback=on_response, group=group)
+ @BaseHandler.auth(admin=True)
+ def delete_all(self, camera_id, group):
+ logging.debug('deleting picture group %(group)s of camera %(id)s' % {
+ 'group': group, 'id': camera_id})
+
+ camera_config = config.get_camera(camera_id)
+ if utils.local_camera(camera_config):
+ try:
+ mediafiles.del_media_group(camera_config, group, 'picture')
+ self.finish_json()
+
+ except Exception as e:
+ self.finish_json({'error': unicode(e)})
+
+ else: # remote camera
+ def on_response(response=None, error=None):
+ if error:
+ return self.finish_json({'error': 'Failed to delete picture group from %(url)s: %(msg)s.' % {
+ 'url': remote.make_camera_url(camera_config), 'msg': error}})
+
+ self.finish_json()
+
+ remote.del_media_group(camera_config, on_response, group=group, media_type='picture')
+
def try_finish(self, content):
try:
self.finish(content)
raise HTTPError(400, 'unknown operation')
@asynchronous
- def post(self, camera_id, op, filename=None):
+ def post(self, camera_id, op, filename=None, group=None):
if camera_id is not None:
camera_id = int(camera_id)
if camera_id not in config.get_camera_ids():
if op == 'delete':
self.delete(camera_id, filename)
+ elif op == 'delete_all':
+ self.delete_all(camera_id, group)
+
else:
raise HTTPError(400, 'unknown operation')
width=self.get_argument('width', None),
height=self.get_argument('height', None))
+ @BaseHandler.auth(admin=True)
def delete(self, camera_id, filename):
logging.debug('deleting movie %(filename)s of camera %(id)s' % {
'filename': filename, 'id': camera_id})
remote.del_media_content(camera_config, on_response, filename=filename, media_type='movie')
+ @BaseHandler.auth(admin=True)
+ def delete_all(self, camera_id, group):
+ logging.debug('deleting movie group %(group)s of camera %(id)s' % {
+ 'group': group, 'id': camera_id})
+
+ camera_config = config.get_camera(camera_id)
+ if utils.local_camera(camera_config):
+ try:
+ mediafiles.del_media_group(camera_config, group, 'movie')
+ self.finish_json()
+
+ except Exception as e:
+ self.finish_json({'error': unicode(e)})
+
+ else: # remote camera
+ def on_response(response=None, error=None):
+ if error:
+ return self.finish_json({'error': 'Failed to delete movie group from %(url)s: %(msg)s.' % {
+ 'url': remote.make_camera_url(camera_config), 'msg': error}})
+
+ self.finish_json()
+
+ remote.del_media_group(camera_config, on_response, group=group, media_type='movie')
+
class UpdateHandler(BaseHandler):
@BaseHandler.auth(admin=True)
url = parts.slice(0, 3).join('/') + uri;
runConfirmDialog('Really delete this file?', function () {
+ showModalDialog('<div class="modal-progress"></div>', null, null, true);
ajax('POST', url, null, function (data) {
+ hideModalDialog(); /* progress */
+ hideModalDialog(); /* confirm */
+
if (data == null || data.error) {
showErrorMessage(data && data.error);
return;
callback();
}
});
+
+ return false;
}, {stack: true});
}
+function doDeleteAllFiles(mediaType, cameraId, groupKey, callback) {
+ runConfirmDialog('Really delete all ' + mediaType + 's in ' + groupKey + '?', function () {
+ showModalDialog('<div class="modal-progress"></div>', null, null, true);
+ ajax('POST', '/' + mediaType + '/' + cameraId + '/delete_all/' + groupKey + '/', null, function (data) {
+ hideModalDialog(); /* progress */
+ hideModalDialog(); /* confirm */
+
+ if (data == null || data.error) {
+ showErrorMessage(data && data.error);
+ return;
+ }
+
+ if (callback) {
+ callback();
+ }
+ });
+
+ return false;
+ }, {stack: true});
+}
/* fetch & push */
dialogDiv.append(groupsDiv);
dialogDiv.append(mediaListDiv);
+ dialogDiv.append(buttonsDiv);
+
+ /* add a temporary div to compute 3em in px */
+ var tempDiv = $('<div style="width: 3em; height: 3em;"></div>');
+ $('div.modal-container').append(tempDiv);
+ var height = tempDiv.height();
+ tempDiv.remove();
+
+ function showGroup(key) {
+ groupKey = key;
+
+ if (mediaListDiv.find('img.media-list-progress').length) {
+ return; /* already in progress of loading */
+ }
+
+ /* (re)set the current state of the group buttons */
+ groupsDiv.find('div.media-dialog-group-button').each(function () {
+ var $this = $(this);
+ if (this.key == key) {
+ $this.addClass('current');
+ }
+ else {
+ $this.removeClass('current');
+ }
+ });
+
+ var mediaListByName = {};
+ var entries = groups[key];
+
+ /* cleanup the media list */
+ mediaListDiv.children('div.media-list-entry').detach();
+ mediaListDiv.html('');
+
+ function addEntries() {
+ /* add the entries to the media list */
+ entries.forEach(function (entry) {
+ var entryDiv = entry.div;
+ var detailsDiv = null;
+
+ if (!entryDiv) {
+ entryDiv = $('<div class="media-list-entry"></div>');
+
+ var previewImg = $('<img class="media-list-preview" src="' + staticUrl + 'img/modal-progress.gif"/>');
+ entryDiv.append(previewImg);
+ previewImg[0]._src = addAuthParams('GET', '/' + mediaType + '/' + cameraId + '/preview' + entry.path + '?height=' + height);
+
+ var downloadButton = $('<div class="media-list-download-button button">Download</div>');
+ entryDiv.append(downloadButton);
+
+ var deleteButton = $('<div class="media-list-delete-button button">Delete</div>');
+
+ if (username === adminUsername) {
+ entryDiv.append(deleteButton);
+ }
+
+ var nameDiv = $('<div class="media-list-entry-name">' + entry.name + '</div>');
+ entryDiv.append(nameDiv);
+
+ detailsDiv = $('<div class="media-list-entry-details"></div>');
+ entryDiv.append(detailsDiv);
+
+ downloadButton.click(function () {
+ downloadFile('/' + mediaType + '/' + cameraId + '/download' + entry.path);
+ return false;
+ });
+
+ deleteButton.click(function () {
+ doDeleteFile('/' + mediaType + '/' + cameraId + '/delete' + entry.path, function () {
+ entryDiv.remove();
+ });
+
+ return false;
+ });
+
+ entryDiv.click(function () {
+ var pos = entries.indexOf(entry);
+ runPictureDialog(entries, pos, mediaType);
+ });
+
+ entry.div = entryDiv;
+ }
+ else {
+ detailsDiv = entry.div.find('div.media-list-entry-details');
+ }
+
+ var momentSpan = $('<span class="details-moment">' + entry.momentStr + ', </span>');
+ var momentShortSpan = $('<span class="details-moment-short">' + entry.momentStrShort + '</span>');
+ var sizeSpan = $('<span class="details-size">' + entry.sizeStr + '</span>');
+ detailsDiv.empty();
+ detailsDiv.append(momentSpan);
+ detailsDiv.append(momentShortSpan);
+ detailsDiv.append(sizeSpan);
+ mediaListDiv.append(entryDiv);
+ });
+
+ /* trigger a scroll event */
+ mediaListDiv.scroll();
+ }
+
+ /* if details are already fetched, simply add the entries and return */
+ if (entries[0].timestamp) {
+ return addEntries();
+ }
+
+ var previewImg = $('<img class="media-list-progress" src="' + staticUrl + 'img/modal-progress.gif"/>');
+ mediaListDiv.append(previewImg);
+
+ var url = '/' + mediaType + '/' + cameraId + '/list/?prefix=' + (key || 'ungrouped');
+ ajax('GET', url, null, function (data) {
+ previewImg.remove();
+
+ if (data == null || data.error) {
+ hideModalDialog();
+ showErrorMessage(data && data.error);
+ return;
+ }
+
+ /* index the media list by name */
+ data.mediaList.forEach(function (media) {
+ var path = media.path;
+ var parts = path.split('/');
+ var name = parts[parts.length - 1];
+
+ mediaListByName[name] = media;
+ });
+
+ /* assign details to entries */
+ entries.forEach(function (entry) {
+ var media = mediaListByName[entry.name];
+ if (media) {
+ entry.momentStr = media.momentStr;
+ entry.momentStrShort = media.momentStrShort;
+ entry.sizeStr = media.sizeStr;
+ entry.timestamp = media.timestamp;
+ }
+ });
+
+ /* sort the entries by timestamp */
+ entries.sortKey(function (e) {return e.timestamp || e.name;}, true);
+
+ addEntries();
+ });
+ }
if (mediaType == 'picture') {
- dialogDiv.append(buttonsDiv);
- var zippedButton = $('<div class="media-dialog-button">Zipped Pictures</div>');
+ var zippedButton = $('<div class="media-dialog-button">Zipped</div>');
buttonsDiv.append(zippedButton);
zippedButton.click(function () {
- if (groupKey) {
+ if (groupKey != null) {
doDownloadZipped(cameraId, groupKey);
}
});
- var timelapseButton = $('<div class="media-dialog-button">Timelapse Movie</div>');
+ var timelapseButton = $('<div class="media-dialog-button">Timelapse</div>');
buttonsDiv.append(timelapseButton);
timelapseButton.click(function () {
- if (groupKey) {
+ if (groupKey != null) {
runTimelapseDialog(cameraId, groupKey, groups[groupKey]);
}
});
}
+
+ var deleteAllButton = $('<div class="media-dialog-button media-dialog-delete-all-button">Delete</div>');
+ buttonsDiv.append(deleteAllButton);
+
+ deleteAllButton.click(function () {
+ if (groupKey != null) {
+ doDeleteAllFiles(mediaType, cameraId, groupKey, function () {
+ /* delete th group button */
+ groupsDiv.find('div.media-dialog-group-button').each(function () {
+ var $this = $(this);
+ if (this.key == groupKey) {
+ $this.remove();
+ }
+ });
+
+ /* delete the group itself */
+ delete groups[groupKey];
+
+ /* show the first existing group, if any */
+ var keys = Object.keys(groups);
+ if (keys.length) {
+ showGroup(keys[0]);
+ }
+ else {
+ hideModalDialog();
+ }
+ });
+ }
+ });
function updateDialogSize() {
var windowWidth = $(window).width();
keys.sort();
keys.reverse();
- /* add a temporary div to compute 3em in px */
- var tempDiv = $('<div style="width: 3em; height: 3em;"></div>');
- $('div.modal-container').append(tempDiv);
- var height = tempDiv.height();
- tempDiv.remove();
-
- function showGroup(key) {
- groupKey = key;
-
- if (mediaListDiv.find('img.media-list-progress').length) {
- return; /* already in progress of loading */
- }
-
- /* (re)set the current state of the group buttons */
- groupsDiv.find('div.media-dialog-group-button').each(function () {
- var $this = $(this);
- if (this.key == key) {
- $this.addClass('current');
- }
- else {
- $this.removeClass('current');
- }
- });
-
- var mediaListByName = {};
- var entries = groups[key];
-
- /* cleanup the media list */
- mediaListDiv.children('div.media-list-entry').detach();
- mediaListDiv.html('');
-
- function addEntries() {
- /* add the entries to the media list */
- entries.forEach(function (entry) {
- var entryDiv = entry.div;
- var detailsDiv = null;
-
- if (!entryDiv) {
- entryDiv = $('<div class="media-list-entry"></div>');
-
- var previewImg = $('<img class="media-list-preview" src="' + staticUrl + 'img/modal-progress.gif"/>');
- entryDiv.append(previewImg);
- previewImg[0]._src = addAuthParams('GET', '/' + mediaType + '/' + cameraId + '/preview' + entry.path + '?height=' + height);
-
- var downloadButton = $('<div class="media-list-download-button button">Download</div>');
- entryDiv.append(downloadButton);
-
- var deleteButton = $('<div class="media-list-delete-button button">Delete</div>');
-
- if (username === adminUsername) {
- entryDiv.append(deleteButton);
- }
-
- var nameDiv = $('<div class="media-list-entry-name">' + entry.name + '</div>');
- entryDiv.append(nameDiv);
-
- detailsDiv = $('<div class="media-list-entry-details"></div>');
- entryDiv.append(detailsDiv);
-
- downloadButton.click(function () {
- downloadFile('/' + mediaType + '/' + cameraId + '/download' + entry.path);
- return false;
- });
-
- deleteButton.click(function () {
- doDeleteFile('/' + mediaType + '/' + cameraId + '/delete' + entry.path, function () {
- entryDiv.remove();
- });
-
- return false;
- });
-
- entryDiv.click(function () {
- var pos = entries.indexOf(entry);
- runPictureDialog(entries, pos, mediaType);
- });
-
- entry.div = entryDiv;
- }
- else {
- detailsDiv = entry.div.find('div.media-list-entry-details');
- }
-
- var momentSpan = $('<span class="details-moment">' + entry.momentStr + ', </span>');
- var momentShortSpan = $('<span class="details-moment-short">' + entry.momentStrShort + '</span>');
- var sizeSpan = $('<span class="details-size">' + entry.sizeStr + '</span>');
- detailsDiv.empty();
- detailsDiv.append(momentSpan);
- detailsDiv.append(momentShortSpan);
- detailsDiv.append(sizeSpan);
- mediaListDiv.append(entryDiv);
- });
-
- /* trigger a scroll event */
- mediaListDiv.scroll();
- }
-
- /* if details are already fetched, simply add the entries and return */
- if (entries[0].timestamp) {
- return addEntries();
- }
-
- var previewImg = $('<img class="media-list-progress" src="' + staticUrl + 'img/modal-progress.gif"/>');
- mediaListDiv.append(previewImg);
-
- var url = '/' + mediaType + '/' + cameraId + '/list/?prefix=' + (key || 'ungrouped');
- ajax('GET', url, null, function (data) {
- previewImg.remove();
-
- if (data == null || data.error) {
- hideModalDialog();
- showErrorMessage(data && data.error);
- return;
- }
-
- /* index the media list by name */
- data.mediaList.forEach(function (media) {
- var path = media.path;
- var parts = path.split('/');
- var name = parts[parts.length - 1];
-
- mediaListByName[name] = media;
- });
-
- /* assign details to entries */
- entries.forEach(function (entry) {
- var media = mediaListByName[entry.name];
- if (media) {
- entry.momentStr = media.momentStr;
- entry.momentStrShort = media.momentStrShort;
- entry.sizeStr = media.sizeStr;
- entry.timestamp = media.timestamp;
- }
- });
-
- /* sort the entries by timestamp */
- entries.sortKey(function (e) {return e.timestamp || e.name;}, true);
-
- addEntries();
- });
- }
-
if (keys.length) {
keys.forEach(function (key) {
var groupButton = $('<div class="media-dialog-group-button"></div>');