discstation 0.1.6 → 0.1.8
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.py +11 -0
- package/src/discstation_host.py +44 -7
package/package.json
CHANGED
package/src/discstation.py
CHANGED
|
@@ -1046,6 +1046,9 @@ def is_rewritable_disc(device):
|
|
|
1046
1046
|
"",
|
|
1047
1047
|
)
|
|
1048
1048
|
return "rw" in media_line
|
|
1049
|
+
# Non-Linux: the RW signal comes from the ID_CDROM_MEDIA_*_RW keys above,
|
|
1050
|
+
# which discstation_host.media_properties() tags from the drutil/diskutil
|
|
1051
|
+
# media type.
|
|
1049
1052
|
return False
|
|
1050
1053
|
|
|
1051
1054
|
|
|
@@ -1110,6 +1113,8 @@ def drive_status(device):
|
|
|
1110
1113
|
does not disturb the tray. Never raises."""
|
|
1111
1114
|
if not device:
|
|
1112
1115
|
return "unknown"
|
|
1116
|
+
if discstation_host.system_name() != "linux":
|
|
1117
|
+
return discstation_host.drive_status()
|
|
1113
1118
|
try:
|
|
1114
1119
|
fd = os.open(device, os.O_RDONLY | os.O_NONBLOCK)
|
|
1115
1120
|
except OSError:
|
|
@@ -1246,6 +1251,12 @@ def _classify_disc(device, props, failed, deadline):
|
|
|
1246
1251
|
print(f"Disc inspection failed: {e}")
|
|
1247
1252
|
kind = kind or "data_disc"
|
|
1248
1253
|
return _disc_info(True, kind, web_type=_web_type_for(kind, 0))
|
|
1254
|
+
if props.get("ID_CDROM_MEDIA_STATE") == "blank":
|
|
1255
|
+
try:
|
|
1256
|
+
cap = discstation_burn.disc_capacity_bytes(device) or 0
|
|
1257
|
+
except Exception:
|
|
1258
|
+
cap = 0
|
|
1259
|
+
return _disc_info(True, "blank", capacity_bytes=cap, web_type="BLANK")
|
|
1249
1260
|
return _disc_info(True, "unknown", web_type="UNKNOWN", failed_probes=failed)
|
|
1250
1261
|
|
|
1251
1262
|
# Fast path for a blank disc: cdrom_id reports this reliably in ~20ms, and
|
package/src/discstation_host.py
CHANGED
|
@@ -144,6 +144,38 @@ def disc_device():
|
|
|
144
144
|
raise FileNotFoundError("No optical disc drive found; set DISC_DEVICE explicitly")
|
|
145
145
|
|
|
146
146
|
|
|
147
|
+
def drive_status():
|
|
148
|
+
"""Non-Linux equivalent of the CDROM_DRIVE_STATUS ioctl.
|
|
149
|
+
Returns 'disc' | 'no_disc' | 'unknown'. macOS: parse `drutil status`."""
|
|
150
|
+
if system_name() != "darwin":
|
|
151
|
+
return "unknown"
|
|
152
|
+
try:
|
|
153
|
+
r = subprocess.run(["/usr/bin/drutil", "status"], capture_output=True,
|
|
154
|
+
text=True, check=False, timeout=4)
|
|
155
|
+
except (OSError, subprocess.TimeoutExpired):
|
|
156
|
+
return "unknown"
|
|
157
|
+
text = (r.stdout + r.stderr).lower()
|
|
158
|
+
if "no media" in text or "media is not present" in text:
|
|
159
|
+
return "no_disc"
|
|
160
|
+
if "name: /dev/disk" in text or "type: cd" in text or "type: dvd" in text \
|
|
161
|
+
or "type: bd" in text:
|
|
162
|
+
return "disc"
|
|
163
|
+
return "unknown"
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def _tag_rewritable(props, media_type):
|
|
167
|
+
"""Set the ID_CDROM_MEDIA_*_RW key that discstation.is_rewritable_disc reads,
|
|
168
|
+
from a lowercased media-type string (drutil 'Type:' or diskutil 'Optical
|
|
169
|
+
Media Type'). ponytail: substring match — same heuristic as the rest of this
|
|
170
|
+
module."""
|
|
171
|
+
if "cd-rw" in media_type or "cdrw" in media_type:
|
|
172
|
+
props["ID_CDROM_MEDIA_CD_RW"] = "1"
|
|
173
|
+
elif "dvd-rw" in media_type or "dvd-ram" in media_type:
|
|
174
|
+
props["ID_CDROM_MEDIA_DVD_RW"] = "1"
|
|
175
|
+
elif "dvd+rw" in media_type or "bd-re" in media_type:
|
|
176
|
+
props["ID_CDROM_MEDIA_DVD_PLUS_RW"] = "1"
|
|
177
|
+
|
|
178
|
+
|
|
147
179
|
def _drutil_media_properties():
|
|
148
180
|
result = subprocess.run(["/usr/bin/drutil", "status"], capture_output=True, text=True, check=False, timeout=3)
|
|
149
181
|
text = result.stdout + result.stderr
|
|
@@ -151,12 +183,16 @@ def _drutil_media_properties():
|
|
|
151
183
|
if result.returncode != 0 or "no media" in lowered:
|
|
152
184
|
return {}
|
|
153
185
|
props = {"ID_CDROM": "1", "ID_CDROM_MEDIA": "1"}
|
|
154
|
-
|
|
186
|
+
blank = "space used:" in lowered and "00:00:00" in lowered.split("space used:", 1)[1][:24]
|
|
187
|
+
if blank:
|
|
155
188
|
props["ID_CDROM_MEDIA_STATE"] = "blank"
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
189
|
+
match = re.search(r"type:\s*([a-z0-9+\-]+)", lowered)
|
|
190
|
+
media_type = match.group(1) if match else ""
|
|
191
|
+
if media_type.startswith("dvd") or media_type.startswith("bd"):
|
|
159
192
|
props["ID_CDROM_MEDIA_TYPE"] = "dvd"
|
|
193
|
+
elif media_type.startswith("cd") and not blank and "-r" not in media_type:
|
|
194
|
+
props["ID_CDROM_MEDIA_TYPE"] = "audio"
|
|
195
|
+
_tag_rewritable(props, media_type)
|
|
160
196
|
return props
|
|
161
197
|
|
|
162
198
|
|
|
@@ -168,7 +204,7 @@ def media_properties(device):
|
|
|
168
204
|
except subprocess.TimeoutExpired:
|
|
169
205
|
return _drutil_media_properties()
|
|
170
206
|
if disk.returncode != 0:
|
|
171
|
-
return
|
|
207
|
+
return _drutil_media_properties()
|
|
172
208
|
fields = {}
|
|
173
209
|
for line in disk.stdout.splitlines():
|
|
174
210
|
if ":" in line:
|
|
@@ -176,7 +212,7 @@ def media_properties(device):
|
|
|
176
212
|
fields[key.strip()] = value.strip()
|
|
177
213
|
optical = fields.get("Optical Media Type", "")
|
|
178
214
|
if not optical and not fields.get("Device / Media Name"):
|
|
179
|
-
return
|
|
215
|
+
return _drutil_media_properties()
|
|
180
216
|
props = {"ID_CDROM": "1", "ID_CDROM_MEDIA": "1"}
|
|
181
217
|
label = fields.get("Volume Name", "")
|
|
182
218
|
filesystem = fields.get("Type (Bundle)") or fields.get("File System Personality")
|
|
@@ -204,8 +240,9 @@ def media_properties(device):
|
|
|
204
240
|
optical = optical.lower()
|
|
205
241
|
if "dvd+r dl" in optical or "dvd-r dl" in optical:
|
|
206
242
|
props["ID_CDROM_MEDIA_DVD_PLUS_R_DL"] = "1"
|
|
207
|
-
elif "dvd+r" in optical or "dvd-r" in optical:
|
|
243
|
+
elif ("dvd+r" in optical or "dvd-r" in optical) and "rw" not in optical:
|
|
208
244
|
props["ID_CDROM_MEDIA_DVD_PLUS_R"] = "1"
|
|
245
|
+
_tag_rewritable(props, optical)
|
|
209
246
|
return props
|
|
210
247
|
return {}
|
|
211
248
|
|