]> www.vanbest.org Git - motioneye-debian/commitdiff
implemented support for choosing disk/partition as target dir
authorCalin Crisan <ccrisan@gmail.com>
Sat, 5 Jul 2014 17:27:15 +0000 (20:27 +0300)
committerCalin Crisan <ccrisan@gmail.com>
Sat, 5 Jul 2014 17:27:15 +0000 (20:27 +0300)
src/config.py
src/diskctl.py
static/js/main.js
templates/main.html

index c1aff345bec780d8c6c9851a246fd754eee4bcb7..ecfedc0bf9fb1388c7ea369ee82cbb310ec78595 100644 (file)
@@ -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', '')
index 92a64f0d50c9acdff1bb36630466223102d3c7c3..e570151f658d7c7d720cd033efecbd3bf0df5f3d 100644 (file)
@@ -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
index dc4fd38e10563160bb67ae0915dbaf915d988d70..d94a8d62ec76be19b58865eb46bfd4b05a095f85 100644 (file)
@@ -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('<option value="' + option + '">' + label + '</option>');
+        });
+    });
+    $('#storageDeviceSelect').append('<option value="custom-path">Custom Path</option>');
+    if (dict['smb_shares']) {
+        $('#storageDeviceSelect').append('<option value="network-share">Network Share</option>');
+    }
+
+    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']);
index dd541e9e1c27657b21cb44f0e33b224b0636894a..7030d221badcd49916f60520a81a8a7ebf974829 100644 (file)
                         <td class="settings-item-label"><span class="settings-item-label">Storage Device</span></td>
                         <td class="settings-item-value">
                             <select class="styled storage" id="storageDeviceSelect">
-                                <option value="local-disk">Local Disk</option>
-                                <option value="network-share">Network Share</option>
                             </select>
                         </td>
                         <td><span class="help-mark" title="indicates the storage device where the image and video files will be saved">?</span></td>