]> www.vanbest.org Git - motioneye-debian/commitdiff
added diskctl.py to list available mounted disks
authorCalin Crisan <ccrisan@gmail.com>
Sat, 5 Jul 2014 15:59:07 +0000 (18:59 +0300)
committerCalin Crisan <ccrisan@gmail.com>
Sat, 5 Jul 2014 16:40:51 +0000 (19:40 +0300)
src/config.py
src/diskctl.py [new file with mode: 0644]
src/mjpgclient.py

index 8faabf6acc32b883b22153ccf8273a87ab4ea635..c1aff345bec780d8c6c9851a246fd754eee4bcb7 100644 (file)
@@ -22,6 +22,7 @@ import re
 
 from collections import OrderedDict
 
+import diskctl
 import motionctl
 import settings
 import smbctl
@@ -282,7 +283,7 @@ def get_camera(camera_id, as_lines=False):
                 camera_config['stream_maxrate'] = camera_config.pop('webcam_maxrate')
             if 'webcam_localhost' in camera_config:
                 camera_config['stream_localhost'] = camera_config.pop('webcam_localhost')
-        
+                
         _set_default_motion_camera(camera_id, camera_config, False)
     
     _camera_config_cache[camera_id] = dict(camera_config)
@@ -704,7 +705,8 @@ def camera_dict_to_ui(data):
         'network_password': data['@network_password'],
         'disk_used': disk_used,
         'disk_total': disk_total,
-        
+        'available_disks': diskctl.list_mounted_disks(),
+
         # text overlay
         'text_overlay': False,
         'left_text': 'camera-name',
diff --git a/src/diskctl.py b/src/diskctl.py
new file mode 100644 (file)
index 0000000..92a64f0
--- /dev/null
@@ -0,0 +1,154 @@
+
+# Copyright (c) 2013 Calin Crisan
+# This file is part of motionEye.
+#
+# motionEye 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 3 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, see <http://www.gnu.org/licenses/>. 
+
+import logging
+import os
+import re
+
+
+def _list_mounts():
+    logging.debug('listing mounts...')
+    
+    mounts = []
+    with open('/proc/mounts', 'r') as f:
+        for line in f:
+            line = line.strip()
+            if not line:
+                continue
+            parts = line.split()
+            if len(parts) < 4:
+                continue
+            
+            target = parts[0]
+            mount_point = parts[1]
+            fstype = parts[2]
+            opts = parts[3]
+
+            if fstype == 'fuseblk':
+                fstype = 'ntfs' # most likely'
+
+            logging.debug('found mount "%s" at "%s"' % (target, mount_point))
+            
+            mounts.append({
+                'target': target,
+                'mount_point': mount_point,
+                'fstype': fstype,
+                'opts': opts,
+            })
+
+    return mounts
+
+
+def _list_disks():
+    logging.debug('listing disks...')
+    
+    disks_by_dev = {}
+    partitions_by_dev = {}
+
+    for entry in os.listdir('/dev/disk/by-id/'):
+        parts = entry.split('-', 1)
+        if len(parts) < 2:
+            continue
+        
+        target = os.path.realpath(os.path.join('/dev/disk/by-id/', entry))
+        
+        bus, entry = parts
+        m = re.search('-part(\d+)$', entry)
+        if m:
+            part_no = int(m.group(1))
+            entry = re.sub('-part\d+$', '', entry)
+        
+        else:
+            part_no = None
+
+        parts = entry.split('_')
+        if len(parts) < 2:
+            vendor = parts[0]
+            model = ''
+        
+        else:
+            vendor, model = parts[:2]
+
+        if part_no is not None:
+            logging.debug('found partition "%s" at "%s" on bus "%s": "%s %s"' % (part_no, target, bus, vendor, model))
+        
+            partitions_by_dev[target] = {
+                'target': target,
+                'bus': bus,
+                'vendor': vendor,
+                'model': model,
+                'part_no': part_no,
+                'unmatched': True
+            }
+            
+        else:
+            logging.debug('found disk at "%s" on bus "%s": "%s %s"' % (target, bus, vendor, model))
+
+            disks_by_dev[target] = {
+                'target': target,
+                'bus': bus,
+                'vendor': vendor,
+                'model': model,
+                'partitions': []
+            }
+        
+    # group partitions by disk
+    for dev, partition in partitions_by_dev.items():
+        for disk_dev, disk in disks_by_dev.items():
+            if dev.startswith(disk_dev):
+                disk['partitions'].append(partition)
+                partition.pop('unmatched')
+            
+    # add separate partitions that did not match any disk
+    for partition in partitions_by_dev.values():
+        if partition.pop('unmatched', False):
+            disks_by_dev[partition['target']] = partition
+            partition['partitions'] = [dict(partition)]
+
+    # prepare flat list of disks
+    disks = disks_by_dev.values()
+    disks.sort(key=lambda d: d['vendor'])
+    
+    for disk in disks:
+        disk['partitions'].sort(key=lambda p: p['part_no'])
+
+    return disks
+
+
+def list_mounted_disks():
+    mounted_disks = []
+    
+    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) 
+        
+            # filter out unmounted partitions
+            disk['partitions'] = [p for p in disk['partitions'] if p.get('mount_point')]
+        
+        # filter out unmounted disks
+        mounted_disks = [d for d in disks if d['partitions']]
+
+    except Exception as e:
+        logging.error('failed to list mounted disks: %s' % e, exc_info=True)
+        
+    return mounted_disks
index 6c8efe0076c47a7ba12e244ba2ea81235d19a9d8..7aad8cd9499699aa36aaf8e6fe4c204492836ed3 100644 (file)
@@ -149,7 +149,8 @@ def _garbage_collector():
             logging.debug('mjpg client timed out receiving data for camera %(camera_id)s on port %(port)s' % {
                     'camera_id': camera_id, 'port': port})
             
-            motionctl.restart() # this will close all the mjpg clients
+            motionctl.stop() # this will close all the mjpg clients
+            motionctl.start() # this will close all the mjpg clients
             
             break