Skip to content

Commit 80a9a06

Browse files
adapt to dockerized whipper
1 parent 4ae83b7 commit 80a9a06

File tree

4 files changed

+105
-80
lines changed

4 files changed

+105
-80
lines changed

Dockerfile

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,23 @@
1-
FROM whipper/whipper
1+
FROM joelametta/whipper
22

33
# required env variables for the script
4-
ENV BEETS_CONFIG=/config.albums-cover.yaml
54
ENV LOG_DIR=/logs
6-
ENV OUTPUT_DIR=/output
75

86
USER root
97

10-
# setup beets
11-
RUN pip install beets \
12-
&& apt-get install -y python-requests \
13-
&& mkdir /home/worker/.config/beets && chown worker: /home/worker/.config/beets
14-
COPY beets.yml /config.albums-cover.yaml
15-
RUN chown worker: /config.albums-cover.yaml \
16-
&& mkdir $LOG_DIR && chown worker: $LOG_DIR
17-
VOLUME "$LOG_DIR"
8+
# setup beets, dependency munkres supports python2 up to 1.0.12
9+
RUN pip install --quiet beets munkres==1.0.12 \
10+
&& apt-get install -yqq python-requests \
11+
&& mkdir /home/worker/.config/beets && chown worker: /home/worker/.config/beets \
12+
&& mkdir -p -- "$LOG_DIR" \
13+
&& chown worker: "$LOG_DIR"
14+
COPY --chown=worker:worker beets.yml /home/worker/.config/beets/config.yaml
1815

19-
# setup script
20-
ENV SCRIPT_PATH=/auto-rip-audio-cd.sh
21-
COPY auto-rip-audio-cd.sh $SCRIPT_PATH
22-
RUN chmod +x $SCRIPT_PATH
16+
# add startup script
17+
COPY auto-rip-audio-cd.sh /auto-rip-audio-cd.sh
18+
RUN chmod +x /auto-rip-audio-cd.sh
2319

20+
VOLUME "$LOG_DIR"
2421
USER worker
2522

2623
ENTRYPOINT ["/auto-rip-audio-cd.sh"]

README.md

Lines changed: 71 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,109 @@
11
# Most Possible Unattended Rip Workflow
22

3-
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__
3+
This project allows you to quickly rip a large collection of audio CD's only with the minimum of manual intervention:
4+
__insert cd - remove cd__
45

56
## Structure
67

78
This project comprises two components:
89

9-
1. A shell script for the actual process:
10+
1. A wrapper shell script for:
1011

11-
- riping, tagging and naming a CD using [whipper](https://github.com/JoeLametta/whipper)
12-
- grab the cover art using [beets](http://beets.io/)
12+
- ripping and tagging (using [whipper](https://github.com/whipper-team/whipper))
13+
- grab the cover art (using [beets](http://beets.io/))
1314
- eject the CD
1415

15-
2. (optional) __UDEV Integration__: A UDEV rule to automatically run the shell script when a CD is being inserted.
16+
2. (optional) A [udev](https://en.wikipedia.org/wiki/Udev) rule to automatically run the shell script when a CD is
17+
being inserted
1618

17-
## Installation
19+
## Installation (Docker based)
1820

19-
First you need to download and extract the project:
21+
It's the easiest way to run this project using docker. However it's still possible to only use the script
22+
`auto-rip-audio-cd.sh`.
2023

21-
curl -L https://github.com/thomas-mc-work/most-possible-unattended-rip/archive/master.tar.gz | tar xz
22-
cd most-possible-unattended-rip-master
24+
### Prepare the working folders
25+
26+
# feel free do change these values
27+
config_dir="$HOME/.config/whipper"
28+
log_dir="$PWD/logs"
29+
output_dir="$PWD/output"
30+
31+
[ ! -d "$config_dir" ] && mkdir -p "$config_dir"
32+
[ ! -d "$log_dir" ] && mkdir -p "$log_dir"
33+
[ ! -d "$output_dir" ] && mkdir -p "$output_dir"
34+
35+
### Build The Container
2336

24-
### Docker
37+
# grab the project
38+
curl -L https://github.com/thomas-mc-work/most-possible-unattended-rip/archive/master.tar.gz | tar xz
39+
40+
# build the container
41+
docker build -t tmcw/mpur most-possible-unattended-rip-master
2542

26-
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).
43+
## Usage
2744

28-
git clone https://github.com/thomas-mc-work/whipper.git
29-
cd whipper
30-
git checkout -b dockerfile
31-
docker build -t whipper/whipper .
32-
# remove the sources again
33-
cd ..
34-
rm -rf whipper
45+
### Initial drive setup
3546

36-
#### Build The Image
47+
First you're required to create a drive specific config file using whipper:
3748

38-
docker build -t tmcw/mpur .
49+
docker run --rm \
50+
--device=/dev/cdrom \
51+
-v "$config_dir:/home/worker/.config/whipper" \
52+
joelametta/whipper drive analyze
3953

40-
#### Run The Container
54+
This is only required once for each drive.
4155

42-
[ ! -d config ] && mkdir config
43-
[ ! -d logs ] && mkdir logs
44-
[ ! -d output ] && mkdir output
56+
### Run The Container
4557

4658
docker run --rm \
4759
--device=/dev/cdrom \
48-
-v "${PWD}/config":/home/worker/.config/whipper \
49-
-v "${PWD}/logs":/logs \
50-
-v "${PWD}/output":/output \
60+
-v "$config_dir:/home/worker/.config/whipper" \
61+
-v "$log_dir:/logs" \
62+
-v "$output_dir:/output" \
5163
tmcw/mpur
5264

53-
### Native
65+
It's recommended to put this command into a shell script (e.g. `$HOME/bin/mpur.sh`)
5466

55-
# Mark the script executable
56-
chmod +x auto-rip-audio-cd.sh
67+
## Classical Setup
68+
69+
### Installation
70+
71+
# prepare the folders by convention
72+
mkdir -p "${HOME}/bin" "${HOME}/.config/beets"
73+
# Install the script and make it executable
74+
curl -Lo "${HOME}/bin/mpur.sh" "https://raw.githubusercontent.com/thomas-mc-work/most-possible-unattended-rip/master/auto-rip-audio-cd.sh"
75+
chmod +x "${HOME}/bin/mpur.sh"
5776
# Install beets via pip
5877
pip install --user beets
5978
# Add the beets configuration
60-
curl -Lo "${HOME}/.config/beets/config.albums-cover.yaml https://raw.githubusercontent.com/thomas-mc-work/most-possible-unattended-rip/master/beets.yml
79+
curl -Lo "${HOME}/.config/beets/config.yaml" "https://raw.githubusercontent.com/thomas-mc-work/most-possible-unattended-rip/master/beets.yml"
80+
81+
### Usage
6182

62-
Now you can simply execute the script after inserting th audio CD:
83+
Now you can simply execute the script after inserting the audio CD:
6384

64-
./auto-rip-audio-cd.sh
85+
$ mpur.sh
6586

66-
### UDEV Integration
87+
#### Parameters
6788

68-
Add a UDEV rule to automatically trigger the script:
89+
- `LOG_DIR`: override the default log files path (`$HOME/logs/audio-rip`)
90+
- `BEETS_CONFIG`: override the default beets config file path (`$HOME/.config/beets/config.yaml`)
6991

70-
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 '<path-to-script>/auto-rip-audio-cd.sh' <username>\"" | sudo tee 80-audio-cd.rules
92+
## udev Integration
7193

72-
Just be sure to substitude the placeholders `<username>` and `<path-to-script>` 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.
94+
Add a udev rule to automatically trigger the script:
7395

74-
**Config File To Control The UDEV Automatism**
96+
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/<username>/bin/mpur.sh' <username>\"" | sudo tee 80-audio-cd.rules
97+
98+
Just be sure to substitute the placeholder `<username>` (or the entire script path) by the appropriate value. The script
99+
will be run with the according user permissions. This is important to get the correct locale settings in the environment.
100+
101+
### Config File Extension
75102

76103
Create a config file in your profiles config (`$HOME/.config`) folder:
77104

78-
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:
105+
If you want to use a config file then you're required to create an intermediate shell script that is invoked by the udev
106+
rule (e.g. `$HOME/bin/mpur-wrapper.sh):
79107

80108
#!/usr/bin/env bash
81109

@@ -96,7 +124,7 @@ If you want to use a config file then you're required to create an intermediate
96124
exit 0
97125
fi
98126

99-
nice -n 19 ionice -c 3 /path/to/auto-rip-audio-cd.sh
127+
nice -n 19 ionice -c 3 $HOME/mpur.sh
100128

101129
# reread the config file to include a late shutdown decision
102130
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
110138
sudo shutdown -h $SHUTDOWN_TIMEOUT
111139
fi
112140

113-
114141
The config file:
115142

116143
# disable auto ripping?
@@ -123,7 +150,8 @@ The config file:
123150
These options are available:
124151

125152
- `DISABLED={0,1}`: Disable the script. Good if you like listen to some music CDs without instantly ripping them
126-
- `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`.
153+
- `SHUTDOWN={0,1}`: You can choose whether to automatically shutdown the system ofter the rip process has finished.
154+
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`.
127155
- `SHUTDOWN_TIMEOUT=<value>`: Lets you define the shutdown timeout
128156

129157
## Links
@@ -134,4 +162,4 @@ These options are available:
134162

135163
---
136164

137-
**Any comments, questions or PRs are very welcome!**
165+
**Any comments, questions or pull requests are very welcome!**

auto-rip-audio-cd.sh

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,55 @@
1-
#!/usr/bin/env bash
1+
#!/usr/bin/env sh
22
# Automated rip process of an audio CD.
3-
set -u
3+
set -o nounset ## set -u : exit the script if you try to use an uninitialised variable
44

55
log_dir=${LOG_DIR:-"$HOME/logs/audio-rip"}
6-
output_dir=${OUTPUT_DIR:-"$HOME/rip"}
7-
beets_config=${BEETS_CONFIG:-"$HOME/.config/beets/config.albums-cover.yaml"}
6+
beets_config=${BEETS_CONFIG:-"$HOME/.config/beets/config.yaml"}
87

8+
mkdir -p -- "$log_dir"
99
log_file="${log_dir}/rip-$(date +%Y-%m-%dT%H-%M-%S).log"
1010

1111
fn_log () {
1212
echo "### $*" | tee -a "$log_file"
1313
}
1414

15-
fn_log "auto rip started"
15+
fn_log "starting rip process with whipper"
1616

1717
# PYTHONIOENCODING: workaround for an issue: https://github.com/JoeLametta/whipper/issues/43
1818
export PYTHONIOENCODING="utf-8"
19-
whipper cd rip --output-directory="$output_dir" -U >> "$log_file" 2>&1
19+
whipper cd rip --unknown 2>&1 | tee -a "$log_file"
2020
sc_whipper=$?
2121

2222
# grab the cover art
23-
if [ $sc_whipper == 0 ]; then
24-
fn_log "whipper rip finished"
25-
26-
# replace the carriage returns with proper line breaks and search for the output pattern
27-
folder_line=$(tr '\015' "\n" < "$log_file" | grep "utput directory")
23+
if [ $sc_whipper = 0 ]; then
24+
# example line:
25+
# INFO:whipper.image.cue:parsing .cue file u'unknown/Unknown Artist - m3JTAxsMcVKGGAiW6CKcaYJ5TG8-/Unknown Artist - m3JTAxsMcVKGGAiW6CKcaYJ5TG8-.cue'
26+
pattern="INFO:whipper\.image\.cue:parsing \.cue file u'.*.cue'"
2827

29-
if [ -z "$folder_line" ]; then
30-
fn_log "result: success (but couldn't find output folder for fetching cover art)"
31-
else
28+
# replace the carriage returns with proper line breaks and search for the output pattern
29+
if cue_file_line=$(tr '\015' "\n" < "$log_file" | grep -E "$pattern"); then
3230
# remove the search pattern
33-
output_path=${folder_line/Creating output directory /}
31+
cue_file=$(echo $cue_file_line | sed "s/.*'\(.*\)'/\1/")
32+
output_path=$(dirname "$cue_file")
3433
fn_log "output path: $output_path"
3534

3635
# Use beets for image grabbing if it is available.
3736
# Can be removed once this is implemented: https://github.com/JoeLametta/whipper/issues/50
3837
if type beet >/dev/null 2>&1; then
38+
fn_log "fetching cover art using beets"
3939
# -l: discard all additions to the library
4040
# -c: path to the config file
4141
# import: normally you import the file here and grab the cover alongside
4242
# -q: quiet - don't ask for user input. Either it works or forget about it
4343
echo a | beet -c "$beets_config" import "$output_path" >> "$log_file"
44-
sc_beets=$?
45-
fn_log "beet result: ${sc_beets}"
46-
exit $sc_beets
44+
exit $?
45+
else
46+
fn_log "failed to find beets to fetch the cover art"
4747
fi
48+
else
49+
fn_log "result: success (but couldn't find output folder for fetching cover art)"
4850
fi
4951
else
50-
fn_log "failed to rip: ${sc_whipper}"
52+
fn_log "whipper failed with status code ${sc_whipper}"
5153
exit $sc_whipper
5254
fi
5355

beets.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
library: /dev/null
2-
31
import:
42
copy: no
53
write: no
64

7-
plugins: fetchart
5+
plugins: fetchart

0 commit comments

Comments
 (0)