From: Calin Crisan Date: Sat, 5 Jul 2014 17:27:15 +0000 (+0300) Subject: implemented support for choosing disk/partition as target dir X-Git-Url: http://www.vanbest.org/gitweb/?a=commitdiff_plain;h=a96784377efc737f18d0d571647d2f3fa94f667b;p=motioneye-debian implemented support for choosing disk/partition as target dir --- diff --git a/src/config.py b/src/config.py index c1aff34..ecfedc0 100644 --- a/src/config.py +++ b/src/config.py @@ -209,7 +209,6 @@ def get_network_shares(): 'share': camera['@network_share_name'], 'username': camera['@network_username'], 'password': camera['@network_password'], - }) return mounts @@ -604,6 +603,16 @@ def camera_ui_to_dict(ui): if ui['root_directory'].startswith('/'): ui['root_directory'] = ui['root_directory'][1:] data['target_dir'] = os.path.join(mount_point, ui['root_directory']) + + elif ui['storage_device'].startswith('local-disk'): + target_dev = ui['storage_device'][10:].replace('-', '/') + mounted_partitions = diskctl.list_mounted_partitions() + partition = mounted_partitions[target_dev] + mount_point = partition['mount_point'] + + if ui['root_directory'].startswith('/'): + ui['root_directory'] = ui['root_directory'][1:] + data['target_dir'] = os.path.normpath(os.path.join(mount_point, ui['root_directory'])) else: data['target_dir'] = ui['root_directory'] @@ -799,6 +808,18 @@ def camera_dict_to_ui(data): mount_point = smbctl.make_mount_point(data['@network_server'], data['@network_share_name'], data['@network_username']) ui['root_directory'] = data['target_dir'][len(mount_point):] + elif data['@storage_device'].startswith('local-disk'): + target_dev = data['@storage_device'][10:].replace('-', '/') + mounted_partitions = diskctl.list_mounted_partitions() + for partition in mounted_partitions.values(): + if partition['target'] == target_dev and data['target_dir'].startswith(partition['mount_point']): + ui['root_directory'] = data['target_dir'][len(partition['mount_point']):] or '/' + break + + else: # not found for some reason + logging.error('could not find mounted partition for device "%s" and target dir "%s"' % (target_dev, data['target_dir'])) + ui['root_directory'] = data['target_dir'] + else: ui['root_directory'] = data['target_dir'] @@ -1086,7 +1107,7 @@ def _set_default_motion_camera(camera_id, data, old_motion): data.setdefault('framerate', 2) data.setdefault('rotate', 0) - data.setdefault('@storage_device', 'local-disk') + data.setdefault('@storage_device', 'custom-path') data.setdefault('@network_server', '') data.setdefault('@network_share_name', '') data.setdefault('@network_username', '') diff --git a/src/diskctl.py b/src/diskctl.py index 92a64f0..e570151 100644 --- a/src/diskctl.py +++ b/src/diskctl.py @@ -152,3 +152,23 @@ def list_mounted_disks(): logging.error('failed to list mounted disks: %s' % e, exc_info=True) return mounted_disks + + +def list_mounted_partitions(): + mounted_partitions = {} + + try: + disks = _list_disks() + mounts_by_target = dict((m['target'], m) for m in _list_mounts()) + + for disk in disks: + for partition in disk['partitions']: + mount = mounts_by_target.get(partition['target']) + if mount: + partition.update(mount) + mounted_partitions[partition['target']] = partition + + except Exception as e: + logging.error('failed to list mounted partitions: %s' % e, exc_info=True) + + return mounted_partitions diff --git a/static/js/main.js b/static/js/main.js index dc4fd38..d94a8d6 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -150,6 +150,15 @@ Array.prototype.sortKey = function (keyFunc, reverse) { }); }; +String.prototype.replaceAll = String.prototype.replaceAll || function (oldStr, newStr) { + var p, s = this; + while ((p = s.indexOf(oldStr)) >= 0) { + s = s.substring(0, p) + newStr + s.substring(p + oldStr.length, s.length); + } + + return s.toString(); +}; + /* UI initialization */ @@ -253,6 +262,16 @@ function initUI() { $('#workingScheduleSwitch').change(updateConfigUi); $('#wifiSwitch').change(updateConfigUi); + $('#storageDeviceSelect').change(function () { + $('#rootDirectoryEntry').val('/'); + }); + + $('#rootDirectoryEntry').change(function () { + if (this.value.charAt(0) !== '/') { + this.value = '/' + this.value; + } + }); + /* fetch & push handlers */ $('#videoDeviceSelect').change(function () { if ($('#videoDeviceSelect').val() === 'add') { @@ -380,16 +399,12 @@ function updateConfigUi() { } /* storage device */ - var smbShares = $('#storageDeviceSelect').data('smb_shares'); - if ($('#storageDeviceSelect').val() === 'local-disk' || !smbShares) { + if ($('#storageDeviceSelect').val() !== 'network-share') { $('#networkServerEntry').parents('tr:eq(0)').each(markHide); $('#networkUsernameEntry').parents('tr:eq(0)').each(markHide); $('#networkPasswordEntry').parents('tr:eq(0)').each(markHide); $('#networkShareNameEntry').parents('tr:eq(0)').each(markHide); } - if (!smbShares) { - $('#storageDeviceSelect').parents('tr:eq(0)').each(markHide); - } /* auto brightness */ if ($('#autoBrightnessSwitch').get(0).checked) { @@ -710,8 +725,38 @@ function dict2CameraUi(dict) { $('#framerateSlider').val(dict['framerate']); /* file storage */ - $('#storageDeviceSelect').data('smb_shares', dict['smb_shares']); - $('#storageDeviceSelect').val(dict['storage_device']); + $('#storageDeviceSelect').empty(); + dict['available_disks'] = dict['available_disks'] || []; + var storageDeviceOptions = {}; + dict['available_disks'].forEach(function (disk) { + disk.partitions.forEach(function (partition) { + var target = partition.target.replaceAll('/', '-'); + var option = 'local-disk' + target; + var label = partition.vendor; + if (partition.model) { + label += ' ' + partition.model; + } + if (disk.partitions.length > 1) { + label += '/part' + partition.part_no; + } + label += ' (' + partition.target + ')'; + + storageDeviceOptions[option] = true; + + $('#storageDeviceSelect').append(''); + }); + }); + $('#storageDeviceSelect').append(''); + if (dict['smb_shares']) { + $('#storageDeviceSelect').append(''); + } + + if (storageDeviceOptions[dict['storage_device']]) { + $('#storageDeviceSelect').val(dict['storage_device']); + } + else { + $('#storageDeviceSelect').val('custom-path'); + } $('#networkServerEntry').val(dict['network_server']); $('#networkShareNameEntry').val(dict['network_share_name']); $('#networkUsernameEntry').val(dict['network_username']); diff --git a/templates/main.html b/templates/main.html index dd541e9..7030d22 100644 --- a/templates/main.html +++ b/templates/main.html @@ -171,8 +171,6 @@ Storage Device ?