More resilient to drive flakiness
This commit is contained in:
parent
d48abf6598
commit
c024de2e6c
|
@ -10,6 +10,7 @@ import io
|
||||||
import shutil
|
import shutil
|
||||||
import time
|
import time
|
||||||
import re
|
import re
|
||||||
|
import logging
|
||||||
|
|
||||||
class Encoder(threading.Thread):
|
class Encoder(threading.Thread):
|
||||||
def __init__(self, directory=None, **kwargs):
|
def __init__(self, directory=None, **kwargs):
|
||||||
|
@ -41,19 +42,20 @@ class Encoder(threading.Thread):
|
||||||
shutil.rmtree(fdir)
|
shutil.rmtree(fdir)
|
||||||
|
|
||||||
def encode_audio(self, fdir, obj):
|
def encode_audio(self, fdir, obj):
|
||||||
print("Not implemented")
|
logging.error("Not implemented")
|
||||||
|
|
||||||
def encode_video(self, fdir, obj):
|
def encode_video(self, fdir, obj):
|
||||||
self.status["state"] = "encoding"
|
self.status["state"] = "encoding"
|
||||||
title = os.path.basename(fdir)
|
title = os.path.basename(fdir)
|
||||||
self.status["title"] = title
|
self.status["title"] = title
|
||||||
print("encoding", title, fdir)
|
logging.info("encoding: %s (%s)" % (title, fdir))
|
||||||
|
|
||||||
outfn = "%s.mkv" % title
|
outfn = "%s.mkv" % title
|
||||||
tmppath = os.path.join(fdir, outfn)
|
tmppath = os.path.join(fdir, outfn)
|
||||||
outpath = os.path.join(self.directory, outfn)
|
outpath = os.path.join(self.directory, outfn)
|
||||||
p = subprocess.Popen(
|
p = subprocess.Popen(
|
||||||
[
|
[
|
||||||
|
"nice",
|
||||||
"HandBrakeCLI",
|
"HandBrakeCLI",
|
||||||
"--json",
|
"--json",
|
||||||
"--input", "%s/VIDEO_TS" % fdir,
|
"--input", "%s/VIDEO_TS" % fdir,
|
||||||
|
|
|
@ -8,6 +8,7 @@ import re
|
||||||
import fcntl
|
import fcntl
|
||||||
import traceback
|
import traceback
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
|
|
||||||
CDROM_DRIVE_STATUS = 0x5326
|
CDROM_DRIVE_STATUS = 0x5326
|
||||||
CDS_NO_INFO = 0
|
CDS_NO_INFO = 0
|
||||||
|
@ -35,12 +36,30 @@ class Reader(threading.Thread):
|
||||||
"device": self.device,
|
"device": self.device,
|
||||||
}
|
}
|
||||||
self.complete = 0
|
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)
|
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):
|
def run(self):
|
||||||
while True:
|
while True:
|
||||||
self.status["state"] = "idle"
|
self.status["state"] = "idle"
|
||||||
|
self.reopen()
|
||||||
|
if not self.drive:
|
||||||
|
time.sleep(30)
|
||||||
|
continue
|
||||||
rv = fcntl.ioctl(self.drive, CDROM_DRIVE_STATUS)
|
rv = fcntl.ioctl(self.drive, CDROM_DRIVE_STATUS)
|
||||||
if rv == CDS_DISC_OK:
|
if rv == CDS_DISC_OK:
|
||||||
rv = fcntl.ioctl(self.drive, CDROM_DISC_STATUS)
|
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]:
|
elif rv in [CDS_DATA_1, CDS_DATA_2]:
|
||||||
self.handle_data()
|
self.handle_data()
|
||||||
else:
|
else:
|
||||||
print("Can't handle disc type %d" % rv)
|
logging.info("Can't handle disc type %d" % rv)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Error in disc handler:", e)
|
logging.error("Error in disc handler: %s" % e)
|
||||||
print(traceback.format_exc())
|
logging.error(traceback.format_exc())
|
||||||
self.eject()
|
self.eject()
|
||||||
|
elif rv == CDS_DISC_OPEN:
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
|
logging.info("CDROM_DRIVE_STATUS: %d (%s)" % (rv, CDS_STR[rv]))
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
|
|
||||||
def eject(self):
|
def eject(self):
|
||||||
|
@ -66,6 +88,7 @@ class Reader(threading.Thread):
|
||||||
fcntl.ioctl(self.drive, CDROM_EJECT)
|
fcntl.ioctl(self.drive, CDROM_EJECT)
|
||||||
return
|
return
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
logging.error("Ejecting: %v" % e)
|
||||||
time.sleep(i * 5)
|
time.sleep(i * 5)
|
||||||
|
|
||||||
def finished(self, **kwargs):
|
def finished(self, **kwargs):
|
||||||
|
@ -106,9 +129,11 @@ class Reader(threading.Thread):
|
||||||
elif l.endswith("KiB"):
|
elif l.endswith("KiB"):
|
||||||
parts = l.split()
|
parts = l.split()
|
||||||
mediaSize += float(parts[-2]) * 1024
|
mediaSize += float(parts[-2]) * 1024
|
||||||
|
if title == "No Label":
|
||||||
|
title = time.strftime("Unknown %Y-%m-%dT%H:%M:%S")
|
||||||
self.status["title"] = title
|
self.status["title"] = title
|
||||||
if mediaSize == 0:
|
if mediaSize == 0:
|
||||||
print("Media size = 0; aborting")
|
logging.info("Media size = 0; aborting")
|
||||||
return
|
return
|
||||||
self.status["size"] = mediaSize
|
self.status["size"] = mediaSize
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
import argparse
|
import argparse
|
||||||
import http.server
|
import http.server
|
||||||
import pathlib
|
import pathlib
|
||||||
|
import logging
|
||||||
|
|
||||||
import reader, encoder, statuser
|
import reader, encoder, statuser
|
||||||
|
|
||||||
|
@ -27,9 +28,11 @@ def main():
|
||||||
parser.add_argument("-incoming", type=pathlib.Path, default="/incoming")
|
parser.add_argument("-incoming", type=pathlib.Path, default="/incoming")
|
||||||
parser.add_argument("-www", type=pathlib.Path, default="/www")
|
parser.add_argument("-www", type=pathlib.Path, default="/www")
|
||||||
parser.add_argument("-port", type=int, default=8080)
|
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()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
readers = []
|
readers = []
|
||||||
for d in args.drive:
|
for d in args.drive:
|
||||||
readers.append(reader.Reader(d, directory=args.incoming, daemon=True))
|
readers.append(reader.Reader(d, directory=args.incoming, daemon=True))
|
||||||
|
|
Loading…
Reference in New Issue