OSXRemovableDrivePlugin.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. # Copyright (c) 2015 Ultimaker B.V.
  2. # Copyright (c) 2013 David Braam
  3. # Uranium is released under the terms of the LGPLv3 or higher.
  4. from . import RemovableDrivePlugin
  5. from UM.Logger import Logger
  6. import subprocess
  7. import os
  8. import plistlib
  9. ## Support for removable devices on Mac OSX
  10. class OSXRemovableDrivePlugin(RemovableDrivePlugin.RemovableDrivePlugin):
  11. def checkRemovableDrives(self):
  12. drives = {}
  13. p = subprocess.Popen(["system_profiler", "SPUSBDataType", "-xml"], stdout = subprocess.PIPE)
  14. plist = plistlib.loads(p.communicate()[0])
  15. result = self._recursiveSearch(plist, "removable_media")
  16. p = subprocess.Popen(["system_profiler", "SPCardReaderDataType", "-xml"], stdout=subprocess.PIPE)
  17. plist = plistlib.loads(p.communicate()[0])
  18. result.extend(self._recursiveSearch(plist, "removable_media"))
  19. for drive in result:
  20. # Ignore everything not explicitly marked as removable
  21. if drive["removable_media"] != "yes":
  22. continue
  23. # Ignore any removable device that does not have an actual volume
  24. if "volumes" not in drive or not drive["volumes"]:
  25. continue
  26. for volume in drive["volumes"]:
  27. if not "mount_point" in volume:
  28. continue
  29. mount_point = volume["mount_point"]
  30. if "_name" in volume:
  31. drive_name = volume["_name"]
  32. else:
  33. drive_name = os.path.basename(mount_point)
  34. drives[mount_point] = drive_name
  35. return drives
  36. def performEjectDevice(self, device):
  37. p = subprocess.Popen(["diskutil", "eject", device.getId()], stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  38. output = p.communicate()
  39. return_code = p.wait()
  40. if return_code != 0:
  41. return False
  42. else:
  43. return True
  44. # Recursively search for key in a plist parsed by plistlib
  45. def _recursiveSearch(self, plist, key):
  46. result = []
  47. for entry in plist:
  48. if key in entry:
  49. result.append(entry)
  50. continue
  51. if "_items" in entry:
  52. result.extend(self._recursiveSearch(entry["_items"], key))
  53. if "Media" in entry:
  54. result.extend(self._recursiveSearch(entry["Media"], key))
  55. return result