From 80a9a066f3a918ca973ffe7b9d5e08fb15637262 Mon Sep 17 00:00:00 2001 From: Thomas McWork Date: Mon, 11 Mar 2019 14:38:20 +0100 Subject: [PATCH] adapt to dockerized whipper --- Dockerfile | 27 +++++----- README.md | 114 +++++++++++++++++++++++++++---------------- auto-rip-audio-cd.sh | 40 +++++++-------- beets.yml | 4 +- 4 files changed, 105 insertions(+), 80 deletions(-) diff --git a/Dockerfile b/Dockerfile index 51b0640..a85c5d7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,26 +1,23 @@ -FROM whipper/whipper +FROM joelametta/whipper # required env variables for the script -ENV BEETS_CONFIG=/config.albums-cover.yaml ENV LOG_DIR=/logs -ENV OUTPUT_DIR=/output USER root -# setup beets -RUN pip install beets \ - && apt-get install -y python-requests \ - && mkdir /home/worker/.config/beets && chown worker: /home/worker/.config/beets -COPY beets.yml /config.albums-cover.yaml -RUN chown worker: /config.albums-cover.yaml \ - && mkdir $LOG_DIR && chown worker: $LOG_DIR -VOLUME "$LOG_DIR" +# setup beets, dependency munkres supports python2 up to 1.0.12 +RUN pip install --quiet beets munkres==1.0.12 \ + && apt-get install -yqq python-requests \ + && mkdir /home/worker/.config/beets && chown worker: /home/worker/.config/beets \ + && mkdir -p -- "$LOG_DIR" \ + && chown worker: "$LOG_DIR" +COPY --chown=worker:worker beets.yml /home/worker/.config/beets/config.yaml -# setup script -ENV SCRIPT_PATH=/auto-rip-audio-cd.sh -COPY auto-rip-audio-cd.sh $SCRIPT_PATH -RUN chmod +x $SCRIPT_PATH +# add startup script +COPY auto-rip-audio-cd.sh /auto-rip-audio-cd.sh +RUN chmod +x /auto-rip-audio-cd.sh +VOLUME "$LOG_DIR" USER worker ENTRYPOINT ["/auto-rip-audio-cd.sh"] diff --git a/README.md b/README.md index c8cc025..a6551e9 100644 --- a/README.md +++ b/README.md @@ -1,81 +1,109 @@ # Most Possible Unattended Rip Workflow -This project allows you to quickly rip a large collection of audio CD's only with the minimum of manual intervention: __insert cd - remove cd__ +This project allows you to quickly rip a large collection of audio CD's only with the minimum of manual intervention: +__insert cd - remove cd__ ## Structure This project comprises two components: -1. A shell script for the actual process: +1. A wrapper shell script for: - - riping, tagging and naming a CD using [whipper](https://github.com/JoeLametta/whipper) - - grab the cover art using [beets](http://beets.io/) + - ripping and tagging (using [whipper](https://github.com/whipper-team/whipper)) + - grab the cover art (using [beets](http://beets.io/)) - eject the CD -2. (optional) __UDEV Integration__: A UDEV rule to automatically run the shell script when a CD is being inserted. +2. (optional) A [udev](https://en.wikipedia.org/wiki/Udev) rule to automatically run the shell script when a CD is +being inserted -## Installation +## Installation (Docker based) -First you need to download and extract the project: +It's the easiest way to run this project using docker. However it's still possible to only use the script +`auto-rip-audio-cd.sh`. - curl -L https://github.com/thomas-mc-work/most-possible-unattended-rip/archive/master.tar.gz | tar xz - cd most-possible-unattended-rip-master +### Prepare the working folders + + # feel free do change these values + config_dir="$HOME/.config/whipper" + log_dir="$PWD/logs" + output_dir="$PWD/output" + + [ ! -d "$config_dir" ] && mkdir -p "$config_dir" + [ ! -d "$log_dir" ] && mkdir -p "$log_dir" + [ ! -d "$output_dir" ] && mkdir -p "$output_dir" + +### Build The Container -### Docker + # grab the project + curl -L https://github.com/thomas-mc-work/most-possible-unattended-rip/archive/master.tar.gz | tar xz + + # build the container + docker build -t tmcw/mpur most-possible-unattended-rip-master -At the moment it's required to build the whipper image yourself as the official Docker support is not yet integrated (https://github.com/JoeLametta/whipper/pull/237). +## Usage - git clone https://github.com/thomas-mc-work/whipper.git - cd whipper - git checkout -b dockerfile - docker build -t whipper/whipper . - # remove the sources again - cd .. - rm -rf whipper +### Initial drive setup -#### Build The Image +First you're required to create a drive specific config file using whipper: - docker build -t tmcw/mpur . + docker run --rm \ + --device=/dev/cdrom \ + -v "$config_dir:/home/worker/.config/whipper" \ + joelametta/whipper drive analyze -#### Run The Container +This is only required once for each drive. - [ ! -d config ] && mkdir config - [ ! -d logs ] && mkdir logs - [ ! -d output ] && mkdir output +### Run The Container docker run --rm \ --device=/dev/cdrom \ - -v "${PWD}/config":/home/worker/.config/whipper \ - -v "${PWD}/logs":/logs \ - -v "${PWD}/output":/output \ + -v "$config_dir:/home/worker/.config/whipper" \ + -v "$log_dir:/logs" \ + -v "$output_dir:/output" \ tmcw/mpur -### Native +It's recommended to put this command into a shell script (e.g. `$HOME/bin/mpur.sh`) - # Mark the script executable - chmod +x auto-rip-audio-cd.sh +## Classical Setup + +### Installation + + # prepare the folders by convention + mkdir -p "${HOME}/bin" "${HOME}/.config/beets" + # Install the script and make it executable + curl -Lo "${HOME}/bin/mpur.sh" "https://raw.githubusercontent.com/thomas-mc-work/most-possible-unattended-rip/master/auto-rip-audio-cd.sh" + chmod +x "${HOME}/bin/mpur.sh" # Install beets via pip pip install --user beets # Add the beets configuration - curl -Lo "${HOME}/.config/beets/config.albums-cover.yaml https://raw.githubusercontent.com/thomas-mc-work/most-possible-unattended-rip/master/beets.yml + curl -Lo "${HOME}/.config/beets/config.yaml" "https://raw.githubusercontent.com/thomas-mc-work/most-possible-unattended-rip/master/beets.yml" + +### Usage -Now you can simply execute the script after inserting th audio CD: +Now you can simply execute the script after inserting the audio CD: - ./auto-rip-audio-cd.sh + $ mpur.sh -### UDEV Integration +#### Parameters -Add a UDEV rule to automatically trigger the script: +- `LOG_DIR`: override the default log files path (`$HOME/logs/audio-rip`) +- `BEETS_CONFIG`: override the default beets config file path (`$HOME/.config/beets/config.yaml`) - echo "SUBSYSTEM==\"block\", SUBSYSTEMS==\"scsi\", KERNEL==\"sr?\", ENV{ID_TYPE}==\"cd\", ENV{ID_CDROM}==\"?*\", ENV{ID_CDROM_MEDIA_TRACK_COUNT_AUDIO}==\"?*\", ACTION==\"change\", RUN+=\"/bin/su -lc '/auto-rip-audio-cd.sh' \"" | sudo tee 80-audio-cd.rules +## udev Integration -Just be sure to substitude the placeholders `` and `` by the appropriate values. The script will be run with the according user permissions. This is important to get the correct locale settings in the environment. +Add a udev rule to automatically trigger the script: -**Config File To Control The UDEV Automatism** + echo "SUBSYSTEM==\"block\", SUBSYSTEMS==\"scsi\", KERNEL==\"sr?\", ENV{ID_TYPE}==\"cd\", ENV{ID_CDROM}==\"?*\", ENV{ID_CDROM_MEDIA_TRACK_COUNT_AUDIO}==\"?*\", ACTION==\"change\", RUN+=\"/bin/su -lc '/home//bin/mpur.sh' \"" | sudo tee 80-audio-cd.rules + +Just be sure to substitute the placeholder `` (or the entire script path) by the appropriate value. The script +will be run with the according user permissions. This is important to get the correct locale settings in the environment. + +### Config File Extension Create a config file in your profiles config (`$HOME/.config`) folder: -If you want to use a config file then you're required to create an intermediate shell script that is invoked by the UDEV rule: +If you want to use a config file then you're required to create an intermediate shell script that is invoked by the udev +rule (e.g. `$HOME/bin/mpur-wrapper.sh): #!/usr/bin/env bash @@ -96,7 +124,7 @@ If you want to use a config file then you're required to create an intermediate exit 0 fi - nice -n 19 ionice -c 3 /path/to/auto-rip-audio-cd.sh + nice -n 19 ionice -c 3 $HOME/mpur.sh # reread the config file to include a late shutdown decision if [ -f "$CONFIG_FILE" ]; then @@ -110,7 +138,6 @@ If you want to use a config file then you're required to create an intermediate sudo shutdown -h $SHUTDOWN_TIMEOUT fi - The config file: # disable auto ripping? @@ -123,7 +150,8 @@ The config file: These options are available: - `DISABLED={0,1}`: Disable the script. Good if you like listen to some music CDs without instantly ripping them - - `SHUTDOWN={0,1}`: You can choose whether to automatically shutdown the system ofter the rip process has finished. This is good e.g. when going to bed and letting the system finish the last CD by itself. For using this you need to have the permission to shutdown the system via the command line. You can achieve this by inserting `%sudo ALL = NOPASSWD: /sbin/shutdown` into `/etc/sudoers`. + - `SHUTDOWN={0,1}`: You can choose whether to automatically shutdown the system ofter the rip process has finished. + This is good e.g. when going to bed and letting the system finish the last CD by itself. For using this you need to have the permission to shutdown the system via the command line. You can achieve this by inserting `%sudo ALL = NOPASSWD: /sbin/shutdown` into `/etc/sudoers`. - `SHUTDOWN_TIMEOUT=`: Lets you define the shutdown timeout ## Links @@ -134,4 +162,4 @@ These options are available: --- -**Any comments, questions or PRs are very welcome!** \ No newline at end of file +**Any comments, questions or pull requests are very welcome!** diff --git a/auto-rip-audio-cd.sh b/auto-rip-audio-cd.sh index ac33aab..49b8cf5 100755 --- a/auto-rip-audio-cd.sh +++ b/auto-rip-audio-cd.sh @@ -1,53 +1,55 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh # Automated rip process of an audio CD. -set -u +set -o nounset ## set -u : exit the script if you try to use an uninitialised variable log_dir=${LOG_DIR:-"$HOME/logs/audio-rip"} -output_dir=${OUTPUT_DIR:-"$HOME/rip"} -beets_config=${BEETS_CONFIG:-"$HOME/.config/beets/config.albums-cover.yaml"} +beets_config=${BEETS_CONFIG:-"$HOME/.config/beets/config.yaml"} +mkdir -p -- "$log_dir" log_file="${log_dir}/rip-$(date +%Y-%m-%dT%H-%M-%S).log" fn_log () { echo "### $*" | tee -a "$log_file" } -fn_log "auto rip started" +fn_log "starting rip process with whipper" # PYTHONIOENCODING: workaround for an issue: https://github.com/JoeLametta/whipper/issues/43 export PYTHONIOENCODING="utf-8" -whipper cd rip --output-directory="$output_dir" -U >> "$log_file" 2>&1 +whipper cd rip --unknown 2>&1 | tee -a "$log_file" sc_whipper=$? # grab the cover art -if [ $sc_whipper == 0 ]; then - fn_log "whipper rip finished" - - # replace the carriage returns with proper line breaks and search for the output pattern - folder_line=$(tr '\015' "\n" < "$log_file" | grep "utput directory") +if [ $sc_whipper = 0 ]; then + # example line: + # INFO:whipper.image.cue:parsing .cue file u'unknown/Unknown Artist - m3JTAxsMcVKGGAiW6CKcaYJ5TG8-/Unknown Artist - m3JTAxsMcVKGGAiW6CKcaYJ5TG8-.cue' + pattern="INFO:whipper\.image\.cue:parsing \.cue file u'.*.cue'" - if [ -z "$folder_line" ]; then - fn_log "result: success (but couldn't find output folder for fetching cover art)" - else + # replace the carriage returns with proper line breaks and search for the output pattern + if cue_file_line=$(tr '\015' "\n" < "$log_file" | grep -E "$pattern"); then # remove the search pattern - output_path=${folder_line/Creating output directory /} + cue_file=$(echo $cue_file_line | sed "s/.*'\(.*\)'/\1/") + output_path=$(dirname "$cue_file") fn_log "output path: $output_path" # Use beets for image grabbing if it is available. # Can be removed once this is implemented: https://github.com/JoeLametta/whipper/issues/50 if type beet >/dev/null 2>&1; then + fn_log "fetching cover art using beets" # -l: discard all additions to the library # -c: path to the config file # import: normally you import the file here and grab the cover alongside # -q: quiet - don't ask for user input. Either it works or forget about it echo a | beet -c "$beets_config" import "$output_path" >> "$log_file" - sc_beets=$? - fn_log "beet result: ${sc_beets}" - exit $sc_beets + exit $? + else + fn_log "failed to find beets to fetch the cover art" fi + else + fn_log "result: success (but couldn't find output folder for fetching cover art)" fi else - fn_log "failed to rip: ${sc_whipper}" + fn_log "whipper failed with status code ${sc_whipper}" exit $sc_whipper fi diff --git a/beets.yml b/beets.yml index 67e9b22..a0bf472 100644 --- a/beets.yml +++ b/beets.yml @@ -1,7 +1,5 @@ -library: /dev/null - import: copy: no write: no -plugins: fetchart \ No newline at end of file +plugins: fetchart