Skip to content

Commit 4ae83b7

Browse files
add Docker support
1 parent cc1ef9d commit 4ae83b7

File tree

6 files changed

+178
-107
lines changed

6 files changed

+178
-107
lines changed

Dockerfile

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
FROM whipper/whipper
2+
3+
# required env variables for the script
4+
ENV BEETS_CONFIG=/config.albums-cover.yaml
5+
ENV LOG_DIR=/logs
6+
ENV OUTPUT_DIR=/output
7+
8+
USER root
9+
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"
18+
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
23+
24+
USER worker
25+
26+
ENTRYPOINT ["/auto-rip-audio-cd.sh"]

README.md

Lines changed: 111 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,137 @@
1-
# Most possible unattended rip workflow
1+
# Most Possible Unattended Rip Workflow
22

3-
This is a script that 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: __insert cd - remove cd__
44

55
## Structure
66

7-
This project comprises three parts:
7+
This project comprises two components:
88

9-
1. A __shell script__:
10-
- rip a cd with [whipper](https://github.com/JoeLametta/whipper) (fka. morituri) with a very low cpu and storage usage priority
11-
- fall back to abcde if that fails
12-
- automatic atgging and naming
13-
- grab the cover art
14-
- eject the cd
9+
1. A shell script for the actual process:
1510

16-
2. (optional) A __udev rule__ to automatically run the shell script when a cd is being inserted.
11+
- riping, tagging and naming a CD using [whipper](https://github.com/JoeLametta/whipper)
12+
- grab the cover art using [beets](http://beets.io/)
13+
- eject the CD
1714

18-
3. (optional) A __config file__ which lets you do some decision regarding the shell script.
19-
20-
All steps within the script are well documented which makes it easy to customize it to any special needs. Furthermore this makes it easy for beginners to understand each step.
15+
2. (optional) __UDEV Integration__: A UDEV rule to automatically run the shell script when a CD is being inserted.
2116

2217
## Installation
2318

24-
1. Simply download the shell script and give it the executable flag:
25-
26-
`wget https://github.com/thomas-mc-work/most-possible-unattended-rip/auto-rip-audio-cd.sh && chmod +x auto-rip-audio-cd.sh`
27-
28-
1b. If you like to use have the script grabbing the cover for you then you need to install [beets](http://beets.io/) (`pip install beets`) and place a special config only for the cover grabbing process into `$HOME/.config/beets/config.albums-cover.yaml`:
29-
30-
import:
31-
copy: no
32-
write: no
33-
34-
plugins: fetchart
19+
First you need to download and extract the project:
20+
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
23+
24+
### Docker
25+
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).
27+
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
35+
36+
#### Build The Image
37+
38+
docker build -t tmcw/mpur .
39+
40+
#### Run The Container
41+
42+
[ ! -d config ] && mkdir config
43+
[ ! -d logs ] && mkdir logs
44+
[ ! -d output ] && mkdir output
45+
46+
docker run --rm \
47+
--device=/dev/cdrom \
48+
-v "${PWD}/config":/home/worker/.config/whipper \
49+
-v "${PWD}/logs":/logs \
50+
-v "${PWD}/output":/output \
51+
tmcw/mpur
52+
53+
### Native
54+
55+
# Mark the script executable
56+
chmod +x auto-rip-audio-cd.sh
57+
# Install beets via pip
58+
pip install --user beets
59+
# 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
61+
62+
Now you can simply execute the script after inserting th audio CD:
63+
64+
./auto-rip-audio-cd.sh
3565

36-
2. (optional) Add a udev rule to automatically trigger the script:
66+
### UDEV Integration
3767

38-
`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`
68+
Add a UDEV rule to automatically trigger the script:
3969

40-
It's important here to replace `<username>` and `<path-to-script>` with 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.
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
4171

42-
3. (optional) Download the config file template into your profiles config (`$HOME/.config`) folder:
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.
4373

44-
`wget https://github.com/thomas-mc-work/most-possible-unattended-rip/auto-rip.cfg -O $HOME/.config/auto-rip.cfg`
74+
**Config File To Control The UDEV Automatism**
4575

46-
These options are available:
76+
Create a config file in your profiles config (`$HOME/.config`) folder:
77+
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:
79+
80+
#!/usr/bin/env bash
81+
82+
# end previous shutdown if one is active
83+
sudo shutdown -c
84+
85+
# marker file for skipping the automated ripping
86+
CONFIG_FILE="${HOME}/.config/auto-rip.cfg"
87+
88+
# include config file
89+
if [ -f "$CONFIG_FILE" ]; then
90+
. "$CONFIG_FILE"
91+
fi
92+
93+
# optionally omit the process by config setting
94+
if [ "$DISABLED" = 1 ]; then
95+
echo "# omitting auto rip due to config setting"
96+
exit 0
97+
fi
98+
99+
nice -n 19 ionice -c 3 /path/to/auto-rip-audio-cd.sh
100+
101+
# reread the config file to include a late shutdown decision
102+
if [ -f "$CONFIG_FILE" ]; then
103+
. "$CONFIG_FILE"
104+
fi
105+
106+
# optionally shutdown after a short delay
107+
if [ "$SHUTDOWN" = 1 ]; then
108+
echo "# shutting down the system"
109+
if ! [[ $SHUTDOWN_TIMEOUT =~ ^[0-9]+$ ]]; then SHUTDOWN_TIMEOUT=3; fi
110+
sudo shutdown -h $SHUTDOWN_TIMEOUT
111+
fi
112+
113+
114+
The config file:
115+
116+
# disable auto ripping?
117+
DISABLED=0
118+
# shutdown after finish?
119+
SHUTDOWN=0
120+
# shutdown timeout in minutes
121+
SHUTDOWN_TIMEOUT=3
122+
123+
These options are available:
47124

48125
- `DISABLED={0,1}`: Disable the script. Good if you like listen to some music CDs without instantly ripping them
49126
- `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`.
50-
- `SHUTDOWN_TIMEOUT=3`: Lets you define the shutdown timeout
127+
- `SHUTDOWN_TIMEOUT=<value>`: Lets you define the shutdown timeout
51128

52129
## Links
53130

54131
- [whipper](https://github.com/JoeLametta/whipper)
55132
- [good explanations and debug help with udev on arch wiki](https://wiki.archlinux.org/index.php/udev)
56133
- [beets](http://beets.io/)
57-
- [abcde best of breed configuration](http://www.andrews-corner.org/linux/abcde/index.html)
58-
- [let abcde grab album art](http://www.andrews-corner.org/linux/abcde/getalbumart.html)
59134

60-
Any comments, questions or PRs are very welcome!
135+
---
136+
137+
**Any comments, questions or PRs are very welcome!**

auto-rip-audio-cd.sh

Lines changed: 29 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,53 @@
11
#!/usr/bin/env bash
2-
# automatisches rippen einer audio-cd
3-
# https://github.com/JoeLametta/whipper
4-
# Vorbereitung morituri:
5-
# # rip offset find
6-
# # rip drive analyze
2+
# Automated rip process of an audio CD.
3+
set -u
74

8-
LOG_DIR="$HOME/logs/audio-rip"
9-
OUTPUT_DIR="$HOME/rip"
5+
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"}
108

11-
# ============
9+
log_file="${log_dir}/rip-$(date +%Y-%m-%dT%H-%M-%S).log"
1210

13-
LOG_FILE="$LOG_DIR/rip-$(date +%Y-%m-%dT%H-%M-%S).log"
11+
fn_log () {
12+
echo "### $*" | tee -a "$log_file"
13+
}
1414

15-
# end previous shutdown if one is active
16-
sudo shutdown -c
17-
18-
# marker file for skipping the automated ripping
19-
CONFIG_FILE="${HOME}/.config/auto-rip.cfg"
20-
21-
# include config file
22-
if [ -f "$CONFIG_FILE" ]; then
23-
. "$CONFIG_FILE"
24-
fi
25-
26-
# optionally omit the process by config setting
27-
if [ "$DISABLED" = 1 ]; then
28-
echo "# omitting auto rip due to config setting" | tee -a "$LOG_FILE"
29-
exit 0
30-
fi
31-
32-
echo "# auto rip started" | tee -a "$LOG_FILE"
15+
fn_log "auto rip started"
3316

3417
# PYTHONIOENCODING: workaround for an issue: https://github.com/JoeLametta/whipper/issues/43
35-
nice -n 19 ionice -c 3 whipper cd rip --output-directory="$OUTPUT_DIR" -U true >>"$LOG_FILE" 2>&1
36-
SC=$?
37-
echo "# auto rip finished" | tee -a "$LOG_FILE"
18+
export PYTHONIOENCODING="utf-8"
19+
whipper cd rip --output-directory="$output_dir" -U >> "$log_file" 2>&1
20+
sc_whipper=$?
3821

3922
# grab the cover art
40-
if [ $SC == 0 ]; then
23+
if [ $sc_whipper == 0 ]; then
24+
fn_log "whipper rip finished"
25+
4126
# replace the carriage returns with proper line breaks and search for the output pattern
42-
FOLDER_LINE=$(tr '\015' "\n" < "${LOG_FILE}" | grep "utput directory")
43-
echo "# folder line: $FOLDER_LINE" >> "${LOG_FILE}"
27+
folder_line=$(tr '\015' "\n" < "$log_file" | grep "utput directory")
4428

45-
if [ "$FOLDER_LINE" == "" ]; then
46-
echo "# result: success (but couldn't find output folder for fetching cover art)" | tee -a "$LOG_FILE"
29+
if [ -z "$folder_line" ]; then
30+
fn_log "result: success (but couldn't find output folder for fetching cover art)"
4731
else
4832
# remove the search pattern
49-
FOLDER=${FOLDER_LINE/Creating output directory /}
50-
echo "# output path: $FOLDER" >> "${LOG_FILE}"
33+
output_path=${folder_line/Creating output directory /}
34+
fn_log "output path: $output_path"
5135

52-
# if you have beets then grab image with beets
53-
# can be removed once this is closed: https://github.com/JoeLametta/whipper/issues/50
36+
# Use beets for image grabbing if it is available.
37+
# Can be removed once this is implemented: https://github.com/JoeLametta/whipper/issues/50
5438
if type beet >/dev/null 2>&1; then
5539
# -l: discard all additions to the library
5640
# -c: path to the config file
5741
# import: normally you import the file here and grab the cover alongside
5842
# -q: quiet - don't ask for user input. Either it works or forget about it
59-
beet -l /dev/null -c "$HOME/.config/beets/config.albums-cover.yaml" import -q "$FOLDER" >> "${LOG_FILE}"
60-
echo "# result: success" | tee -a "$LOG_FILE"
43+
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
6147
fi
6248
fi
6349
else
64-
echo "# result: no success with whipper/morituri: status code = ${SC}" | tee -a "$LOG_FILE"
65-
66-
# if you have abcde then use it as fallback
67-
if type abcde >/dev/null 2>&1; then
68-
echo "# trying abcde" | tee -a "$LOG_FILE"
69-
abcde | tee -a "$LOG_FILE"
70-
SC=$?
71-
72-
if [ $SC == 0 ]; then
73-
echo "# result: success with abcde" | tee -a "$LOG_FILE"
74-
eject
75-
else
76-
echo "# result: no success with abcde: status code = ${SC}" | tee -a "$LOG_FILE"
77-
fi
78-
fi
50+
fn_log "failed to rip: ${sc_whipper}"
51+
exit $sc_whipper
7952
fi
8053

81-
# reread the config file to include a late shutdown decision
82-
if [ -f "$CONFIG_FILE" ]; then
83-
. "$CONFIG_FILE"
84-
fi
85-
86-
# optionally shutdown after a short delay
87-
if [ "$SHUTDOWN" = 1 ]; then
88-
echo "# shutting down the system" | tee -a "$LOG_FILE"
89-
if ! [[ $SHUTDOWN_TIMEOUT =~ ^[0-9]+$ ]]; then SHUTDOWN_TIMEOUT=3; fi
90-
sudo shutdown -h $SHUTDOWN_TIMEOUT | tee -a "$LOG_FILE"
91-
fi

auto-rip.cfg

Lines changed: 0 additions & 6 deletions
This file was deleted.

beets.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
library: /dev/null
2+
3+
import:
4+
copy: no
5+
write: no
6+
7+
plugins: fetchart

docker-build-image.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/env sh
2+
set -o nounset ## set -u : exit the script if you try to use an uninitialised variable
3+
set -o errexit ## set -e : exit the script if any statement returns a non-true return value
4+
5+
docker build -t tmcw/mpur:0.6-1 -t tmcw/mpur:latest .

0 commit comments

Comments
 (0)