discstation 0.1.39 → 0.1.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/discstation_host.py +26 -5
package/package.json
CHANGED
package/src/discstation_host.py
CHANGED
|
@@ -184,6 +184,22 @@ def _mac_optical_device():
|
|
|
184
184
|
|
|
185
185
|
_last_disc_device = None
|
|
186
186
|
|
|
187
|
+
|
|
188
|
+
class NoMediaError(FileNotFoundError):
|
|
189
|
+
"""The optical drive is present but has no disc it can see."""
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def _mac_drive_name():
|
|
193
|
+
"""Drive model from ioreg, which lists it whether or not a disc is loaded
|
|
194
|
+
(the /dev/diskN node only exists while media is)."""
|
|
195
|
+
try:
|
|
196
|
+
out = subprocess.run(["/usr/sbin/ioreg", "-r", "-c", "IODVDServices", "-l"],
|
|
197
|
+
capture_output=True, text=True, check=False, timeout=3).stdout
|
|
198
|
+
except (OSError, subprocess.TimeoutExpired):
|
|
199
|
+
return None
|
|
200
|
+
m = re.search(r'"Product Name"="([^"]+)"', out)
|
|
201
|
+
return m.group(1) if m else None
|
|
202
|
+
|
|
187
203
|
# --- Windows: IMAPI2 / WMI probes via bundled PowerShell helpers ---------------
|
|
188
204
|
_WIN_DIR = Path(__file__).resolve().parent / "win"
|
|
189
205
|
_win_info_cache = (0.0, None)
|
|
@@ -259,6 +275,9 @@ def disc_device():
|
|
|
259
275
|
# known node so the caller can still probe it (it just reports no media).
|
|
260
276
|
if _last_disc_device:
|
|
261
277
|
return _last_disc_device
|
|
278
|
+
drive = _mac_drive_name()
|
|
279
|
+
if drive:
|
|
280
|
+
raise NoMediaError(f"Drive found ({drive}) but no disc is readable")
|
|
262
281
|
elif override:
|
|
263
282
|
return override
|
|
264
283
|
|
|
@@ -272,7 +291,7 @@ def disc_device():
|
|
|
272
291
|
return str(drives[0])
|
|
273
292
|
elif system == "darwin":
|
|
274
293
|
try:
|
|
275
|
-
status = subprocess.run(["/usr/bin/drutil", "status"], capture_output=True, text=True, check=False, timeout=
|
|
294
|
+
status = subprocess.run(["/usr/bin/drutil", "status"], capture_output=True, text=True, check=False, timeout=15)
|
|
276
295
|
except (OSError, subprocess.TimeoutExpired):
|
|
277
296
|
status = None
|
|
278
297
|
if status:
|
|
@@ -304,7 +323,7 @@ def drive_status():
|
|
|
304
323
|
return "unknown"
|
|
305
324
|
try:
|
|
306
325
|
r = subprocess.run(["/usr/bin/drutil", "status"], capture_output=True,
|
|
307
|
-
text=True, check=False, timeout=
|
|
326
|
+
text=True, check=False, timeout=15)
|
|
308
327
|
except (OSError, subprocess.TimeoutExpired):
|
|
309
328
|
return "unknown"
|
|
310
329
|
text = (r.stdout + r.stderr).lower()
|
|
@@ -330,7 +349,7 @@ def _tag_rewritable(props, media_type):
|
|
|
330
349
|
|
|
331
350
|
|
|
332
351
|
def _drutil_media_properties():
|
|
333
|
-
result = subprocess.run(["/usr/bin/drutil", "status"], capture_output=True, text=True, check=False, timeout=
|
|
352
|
+
result = subprocess.run(["/usr/bin/drutil", "status"], capture_output=True, text=True, check=False, timeout=15)
|
|
334
353
|
text = result.stdout + result.stderr
|
|
335
354
|
lowered = text.lower()
|
|
336
355
|
if result.returncode != 0 or "no media" in lowered:
|
|
@@ -382,7 +401,9 @@ def media_properties(device):
|
|
|
382
401
|
mount_point = fields.get("Mount Point", "")
|
|
383
402
|
if mount_point and mount_point != "Not applicable":
|
|
384
403
|
props["ID_MOUNT_POINT"] = mount_point
|
|
385
|
-
if label.lower() == "audio cd":
|
|
404
|
+
if label.lower() == "audio cd" or props.get("ID_FS_TYPE") == "cddafs":
|
|
405
|
+
# cddafs is macOS's filesystem for Red Book audio - the only signal
|
|
406
|
+
# that works for a burned CD-R, whose media type ("CD-R") has an "r".
|
|
386
407
|
props["ID_CDROM_MEDIA_TYPE"] = "audio"
|
|
387
408
|
elif "cd" in optical.lower() and "r" not in optical.lower():
|
|
388
409
|
props["ID_CDROM_MEDIA_TYPE"] = "audio"
|
|
@@ -430,7 +451,7 @@ def media_capacity_bytes(device):
|
|
|
430
451
|
try:
|
|
431
452
|
result = subprocess.run(["/usr/sbin/diskutil", "info", device], capture_output=True, text=True, check=False, timeout=3)
|
|
432
453
|
except subprocess.TimeoutExpired:
|
|
433
|
-
result = subprocess.run(["/usr/bin/drutil", "status"], capture_output=True, text=True, check=False, timeout=
|
|
454
|
+
result = subprocess.run(["/usr/bin/drutil", "status"], capture_output=True, text=True, check=False, timeout=15)
|
|
434
455
|
match = re.search(r"blocks:\s*(\d+)\s*/", result.stdout + result.stderr, re.IGNORECASE)
|
|
435
456
|
if match:
|
|
436
457
|
return int(match.group(1)) * 2048
|