#! /usr/bin/python3 import subprocess import time import logging import re import os import socket import io import gnudb SECOND = 1 MINUTE = 60 * SECOND HOUR = 60 * MINUTE def read(device, status): # Get disc ID p = subprocess.run( [ "cd-discid", device, ], encoding="utf-8", capture_output=True, ) discid = p.stdout status["discid"] = discid # Look it up in cddb email = os.environ.get("EMAIL") # You should really set this variable, tho if not email: user = "user" try: user = os.getlogin() except OSError: pass email = "%s@%s" % (user, socket.gethostname()) db_server = gnudb.Server(email) disc = db_server.bestguess(discid) if disc: # There was a hit! Hooray! # We're expected to be automatic here, # so just use the first one. for k in ("title", "artist", "genre", "year", "tracks"): status[k] = disc[k] else: now = time.strftime("%Y-%m-%dT%H%M%S") num_tracks = int(discid.split()[1]) status["title"] = "Unknown CD - %s" % now status["tracks"] = [""] * num_tracks def rip(device, status, directory): # cdparanoia reports completion in samples # use discid duration to figure out total number of samples duration = int(status["discid"].split()[-1]) * SECOND # disc duration in seconds total_samples = duration * (75 / SECOND) * 1176 # 75 sectors per second, 1176 samples per sector track_num = 1 for track_name in status["tracks"]: logging.debug("Ripping track %d of %d", track_num, len(status["tracks"])) p = subprocess.Popen( [ "cdparanoia", "--stderr-progress", "--force-cdrom-device", device, "--batch", str(track_num), ], cwd = directory, stderr = subprocess.PIPE, encoding = "utf-8", ) for line in p.stderr: line = line.strip() if line.startswith("##: -2"): samples = int(line.split()[-1]) status["complete"] = samples / total_samples track_num += 1 def encode(status, directory): # Encode the tracks track_num = 1 for track_name in status["tracks"]: argv = [ "lame", "--preset", "standard", "-tl", status["title"], "--tn", "%d/%d" % (track_num, len(status["tracks"])), ] if status["artist"]: argv.extend(["-ta", status["artist"]]) if status["genre"]: argv.extend(["-tg", status["genre"]]) if status["year"]: argv.extend(["-ty", status["year"]]) if track_name: argv.extend(["-tt", track_name]) outfn = "%d - %s.mp3" % (track_num, track_name) else: outfn = "%d.mp3" % track_num argv.append("track%02d.cdda.wav" % track_num) argv.append(outfn) p = subprocess.Popen( argv, cwd = directory, stdin = subprocess.PIPE, encoding = "utf-8", ) p.communicate(input=track_name) track_num += 1 if __name__ == "__main__": import pprint logging.basicConfig(level=logging.DEBUG) status = {} read("/dev/sr0", status) pprint.pprint(status) directory = os.path.join(".", status["title"]) os.makedirs(directory, exist_ok=True) rip("/dev/sr0", status, directory) pprint.pprint(status) encode(status, directory) pprint.pprint(status) # vi: sw=4 ts=4 et ai