From c024de2e6c0cd1b5927b5e45af45882753e729b5 Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Sat, 20 Aug 2022 16:42:53 -0600 Subject: [PATCH] More resilient to drive flakiness --- src/encoder.py | 6 ++++-- src/reader.py | 37 +++++++++++++++++++++++++++++++------ src/sucker.py | 5 ++++- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/encoder.py b/src/encoder.py index ec5a9bf..b9987f9 100644 --- a/src/encoder.py +++ b/src/encoder.py @@ -10,6 +10,7 @@ import io import shutil import time import re +import logging class Encoder(threading.Thread): def __init__(self, directory=None, **kwargs): @@ -41,19 +42,20 @@ class Encoder(threading.Thread): shutil.rmtree(fdir) def encode_audio(self, fdir, obj): - print("Not implemented") + logging.error("Not implemented") def encode_video(self, fdir, obj): self.status["state"] = "encoding" title = os.path.basename(fdir) self.status["title"] = title - print("encoding", title, fdir) + logging.info("encoding: %s (%s)" % (title, fdir)) outfn = "%s.mkv" % title tmppath = os.path.join(fdir, outfn) outpath = os.path.join(self.directory, outfn) p = subprocess.Popen( [ + "nice", "HandBrakeCLI", "--json", "--input", "%s/VIDEO_TS" % fdir, diff --git a/src/reader.py b/src/reader.py index b4ede0a..0c1a61d 100644 --- a/src/reader.py +++ b/src/reader.py @@ -8,12 +8,13 @@ import re import fcntl import traceback import json +import logging CDROM_DRIVE_STATUS = 0x5326 CDS_NO_INFO = 0 CDS_NO_DISC = 1 CDS_TRAY_OPEN = 2 -CDS_DRIVE_NOT_READ =3 +CDS_DRIVE_NOT_READ = 3 CDS_DISC_OK = 4 CDS_STR = ["no info", "no disc", "tray open", "drive not read", "disc ok"] @@ -35,12 +36,30 @@ class Reader(threading.Thread): "device": self.device, } self.complete = 0 - self.drive = os.open(device, os.O_RDONLY | os.O_NONBLOCK) + self.staleness = 0 + self.drive = None + logging.info("Starting reader on %s" % self.device) return super().__init__(**kwargs) + 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 + def run(self): while True: self.status["state"] = "idle" + self.reopen() + if not self.drive: + time.sleep(30) + continue rv = fcntl.ioctl(self.drive, CDROM_DRIVE_STATUS) if rv == CDS_DISC_OK: rv = fcntl.ioctl(self.drive, CDROM_DISC_STATUS) @@ -50,12 +69,15 @@ class Reader(threading.Thread): elif rv in [CDS_DATA_1, CDS_DATA_2]: self.handle_data() else: - print("Can't handle disc type %d" % rv) + logging.info("Can't handle disc type %d" % rv) except Exception as e: - print("Error in disc handler:", e) - print(traceback.format_exc()) + logging.error("Error in disc handler: %s" % e) + logging.error(traceback.format_exc()) self.eject() + elif rv == CDS_DISC_OPEN: + pass else: + logging.info("CDROM_DRIVE_STATUS: %d (%s)" % (rv, CDS_STR[rv])) time.sleep(3) def eject(self): @@ -66,6 +88,7 @@ class Reader(threading.Thread): fcntl.ioctl(self.drive, CDROM_EJECT) return except Exception as e: + logging.error("Ejecting: %v" % e) time.sleep(i * 5) def finished(self, **kwargs): @@ -106,9 +129,11 @@ class Reader(threading.Thread): elif l.endswith("KiB"): parts = l.split() mediaSize += float(parts[-2]) * 1024 + if title == "No Label": + title = time.strftime("Unknown %Y-%m-%dT%H:%M:%S") self.status["title"] = title if mediaSize == 0: - print("Media size = 0; aborting") + logging.info("Media size = 0; aborting") return self.status["size"] = mediaSize diff --git a/src/sucker.py b/src/sucker.py index 9325c84..0c91b74 100644 --- a/src/sucker.py +++ b/src/sucker.py @@ -3,6 +3,7 @@ import argparse import http.server import pathlib +import logging import reader, encoder, statuser @@ -27,9 +28,11 @@ def main(): parser.add_argument("-incoming", type=pathlib.Path, default="/incoming") parser.add_argument("-www", type=pathlib.Path, default="/www") parser.add_argument("-port", type=int, default=8080) - parser.add_argument("-drive", nargs="+", default=["/dev/sr0"]) + parser.add_argument("-drive", nargs="+", default=["/dev/sr0", "/dev/sr1"]) args = parser.parse_args() + logging.basicConfig(level=logging.INFO) + readers = [] for d in args.drive: readers.append(reader.Reader(d, directory=args.incoming, daemon=True))