media-sucker/src/reader.py

114 lines
3.2 KiB
Python
Raw Normal View History

2022-02-26 08:05:20 -07:00
#! /usr/bin/python3
import os
import threading
import subprocess
import time
import re
import fcntl
2022-05-24 17:23:12 -06:00
import traceback
2022-08-21 15:58:11 -06:00
import json
2022-08-20 16:42:53 -06:00
import logging
2022-08-21 15:58:11 -06:00
import dvd
2022-02-26 08:05:20 -07:00
CDROM_DRIVE_STATUS = 0x5326
CDS_NO_INFO = 0
CDS_NO_DISC = 1
CDS_TRAY_OPEN = 2
2022-08-20 16:42:53 -06:00
CDS_DRIVE_NOT_READ = 3
2022-02-26 08:05:20 -07:00
CDS_DISC_OK = 4
CDS_STR = ["no info", "no disc", "tray open", "drive not read", "disc ok"]
CDROM_DISC_STATUS = 0x5327
CDS_AUDIO = 100
CDS_DATA_1 = 101
CDS_DATA_2 = 102
CDROM_LOCKDOOR = 0x5329
CDROM_EJECT = 0x5309
class Reader(threading.Thread):
def __init__(self, device, directory=None, **kwargs):
self.device = device
self.directory = directory
self.status = {
"type": "reader",
"state": "idle",
"device": self.device,
}
self.complete = 0
2022-08-20 16:42:53 -06:00
self.staleness = 0
self.drive = None
logging.info("Starting reader on %s" % self.device)
2022-02-26 08:05:20 -07:00
return super().__init__(**kwargs)
2022-08-20 16:42:53 -06:00
def reopen(self):
if (self.staleness > 15) or not self.drive:
self.drive = None # Close existing
try:
self.drive = os.open(self.device, os.O_RDONLY | os.O_NONBLOCK)
logging.info("Reopened %s" % self.device)
except FileNotFoundError:
pass
self.staleness = 0
else:
self.staleness += 1
2022-02-26 08:05:20 -07:00
def run(self):
while True:
self.status["state"] = "idle"
2022-08-20 16:42:53 -06:00
self.reopen()
if not self.drive:
time.sleep(30)
continue
2022-02-26 08:05:20 -07:00
rv = fcntl.ioctl(self.drive, CDROM_DRIVE_STATUS)
if rv == CDS_DISC_OK:
rv = fcntl.ioctl(self.drive, CDROM_DISC_STATUS)
try:
if rv == CDS_AUDIO:
self.handle_audio()
elif rv in [CDS_DATA_1, CDS_DATA_2]:
self.handle_data()
else:
2022-08-20 16:42:53 -06:00
logging.info("Can't handle disc type %d" % rv)
2022-02-26 08:05:20 -07:00
except Exception as e:
2022-08-20 16:42:53 -06:00
logging.error("Error in disc handler: %s" % e)
logging.error(traceback.format_exc())
2022-02-26 08:05:20 -07:00
self.eject()
2022-08-21 17:22:06 -06:00
elif rv == CDS_TRAY_OPEN:
time.sleep(3)
2022-02-26 08:05:20 -07:00
else:
2022-08-20 16:42:53 -06:00
logging.info("CDROM_DRIVE_STATUS: %d (%s)" % (rv, CDS_STR[rv]))
2022-02-26 08:05:20 -07:00
time.sleep(3)
def eject(self):
self.status["state"] = "ejecting"
2022-08-21 15:58:11 -06:00
2022-02-26 08:05:20 -07:00
for i in range(20):
try:
fcntl.ioctl(self.drive, CDROM_LOCKDOOR, 0)
fcntl.ioctl(self.drive, CDROM_EJECT)
return
except Exception as e:
2022-08-20 16:42:53 -06:00
logging.error("Ejecting: %v" % e)
2022-02-26 08:05:20 -07:00
time.sleep(i * 5)
def finished(self, **kwargs):
self.status["state"] = "finished read"
2022-08-21 15:58:11 -06:00
fn = os.path.join(self.directory, self.status["title"], "sucker.json")
2022-02-26 08:05:20 -07:00
newfn = fn + ".new"
2022-05-24 17:23:12 -06:00
with open(newfn, "w") as fout:
2022-02-26 08:05:20 -07:00
json.dump(obj=self.status, fp=fout)
os.rename(src=newfn, dst=fn)
def handle_audio(self):
pass # XXX
def handle_data(self):
2022-08-21 17:22:06 -06:00
self.status["video"] = True
src = dvd.Copier(self.device, self.status)
2022-08-21 15:58:11 -06:00
src.copy(self.directory)
2022-02-26 08:05:20 -07:00
self.finished()
# vi: sw=4 ts=4 et ai