9 from xml.etree import cElementTree as ElementTree
11 from xml.etree import ElementTree
13 _removeableCache = None
14 _removeableCacheTime = None
16 def _parseStupidPListXML(e):
18 return _parseStupidPListXML(list(e)[0])
22 ret.append(_parseStupidPListXML(c))
31 ret[key] = _parseStupidPListXML(c)
40 def _findInTree(t, n):
43 if '_name' in t and t['_name'] == n:
45 for k, v in t.items():
46 ret += _findInTree(v, n)
49 ret += _findInTree(v, n)
52 def getPossibleSDcardDrives():
53 global _removeableCache, _removeableCacheTime
54 if _removeableCache is not None and time.time() - _removeableCacheTime < 5.0:
55 return _removeableCache
58 if platform.system() == "Windows":
59 from ctypes import windll
61 bitmask = windll.kernel32.GetLogicalDrives()
62 for letter in string.uppercase:
63 if bitmask & 1 and windll.kernel32.GetDriveTypeA(letter + ':/') == 2:
65 nameBuffer = ctypes.create_unicode_buffer(1024)
66 if windll.kernel32.GetVolumeInformationW(ctypes.c_wchar_p(letter + ':/'), nameBuffer, ctypes.sizeof(nameBuffer), None, None, None, None, 0) == 0:
67 volumeName = nameBuffer.value
69 volumeName = 'NO NAME'
71 freeBytes = ctypes.c_longlong(0)
72 if windll.kernel32.GetDiskFreeSpaceExA(letter + ':/', ctypes.byref(freeBytes), None, None) == 0:
74 if freeBytes.value < 1:
76 drives.append(('%s (%s:)' % (volumeName, letter), letter + ':/', volumeName))
78 elif platform.system() == "Darwin":
79 p = subprocess.Popen(['system_profiler', 'SPUSBDataType', '-xml'], stdout=subprocess.PIPE)
80 xml = ElementTree.fromstring(p.communicate()[0])
83 xml = _parseStupidPListXML(xml)
84 for dev in _findInTree(xml, 'Mass Storage Device'):
85 if 'removable_media' in dev and dev['removable_media'] == 'yes' and 'volumes' in dev and len(dev['volumes']) > 0:
86 for vol in dev['volumes']:
87 if 'mount_point' in vol:
88 volume = vol['mount_point']
89 drives.append((os.path.basename(volume), volume, os.path.basename(volume)))
91 for volume in glob.glob('/media/*'):
92 drives.append((os.path.basename(volume), volume, os.path.basename(volume)))
94 _removeableCache = drives
95 _removeableCacheTime = time.time()
98 def ejectDrive(driveName):
99 if platform.system() == "Windows":
100 cmd = '"%s" %s>NUL' % (os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'EjectMedia.exe')), driveName)
101 elif platform.system() == "Darwin":
102 cmd = "diskutil eject '%s' > /dev/null 2>&1" % (driveName)
104 cmd = "umount '%s' > /dev/null 2>&1" % (driveName)
110 if __name__ == '__main__':
111 print getPossibleSDcardDrives()