Skip to content

Instantly share code, notes, and snippets.

@ScoreUnder
Last active August 29, 2015 14:27
Show Gist options
  • Save ScoreUnder/b189e9b7734543e8f2d5 to your computer and use it in GitHub Desktop.
Save ScoreUnder/b189e9b7734543e8f2d5 to your computer and use it in GitHub Desktop.
skullmp3 downloader gui thing
#!/bin/sh
title="mp3skull downloader"
put() { eval 'printf %s\\n "$'"$1"'"'; }
music_dir=$(xdg-user-dir MUSIC || put HOME)
cleanup() {
ret=$?
rm -f -- "$cookie_jar"
trap - EXIT
exit "$ret"
}
cookie_jar=
trap cleanup EXIT INT HUP TERM
cookie_jar=$(mktemp)
err() {
zenity --error --title "$title" --text "$*"
exit 1
}
parse_mp3_results() {
awk '
function striptags(s) {
gsub(/<[^>]*>/,"",s)
sub(/^ */,"",s)
sub(/ *$/,"",s)
return s
}
/class="mp3_title"/ {
parse=1
name=""
duration=""
bitrate=""
details=""
link=""
}
parse && /class="play_button"/ {
parse=0
print bitrate
print details
print name
print link
}
parse && /class="mp3_title"/ {
$0=substr($0, index($0, ">") + 1)
name=striptags($0)
}
parse && /class='\''songInfoMobile'\''/ {
getline
$0=striptags($0)
if ($2 == "kbps") {
bitrate=sprintf("%03d",$1)
sub("[^/]*/ ?","")
}
details=striptags($0)
}
parse && /class="download_button"/ {
$0=substr($0,index($0,"href=")+6)
sub(/".*$/,"")
link=$0
}
'
}
select_mp3_results() {
zenity --list --title "$title" --column Bitrate --column Details --column Name --column Link --multiple --print-column=4
}
url_basename() {
local url
url=$1
url=${url%%'#'*}
url=${url%%'?'*}
url=${url##*/}
put url
}
make_filename_from_url() {
local name
name=$(url_basename "$1")
# Ensure it ends in mp3
name=${name%?mp3}.mp3
# lol race condition (ensure no filename collisions)
while [ -e "$name" ]; do name="new-$name"; done
put name
}
fancy_progress_meter() {
stdbuf -oL awk 'BEGIN{RS="\r"}$1~/[0-9]/{print $1}' | tee /proc/self/fd/2 | zenity --progress "$@"
}
launch_download() {
filename=$(make_filename_from_url "$1")
pipe=$(mktemp -u)
mkfifo -- "$pipe" || exit
(<"$pipe" fancy_progress_meter --title "$title" --text "$filename" --no-cancel) &
exec 2>"$pipe"
rm -- "$pipe"
stdbuf -o0 curl -g -o "$filename" -- "$1" || err "Failed to download $url"
}
fckh=$(curl -L -c "$cookie_jar" https://mp3skull.is/\? | grep -o 'name="fckh".*$' | cut -d\" -f4 | head -n1)
[ -n "$fckh" ] || err 'Could not fetch session ID from mp3skull.is'
terms=$(zenity --entry --title "$title" --text "Enter search terms:") || exit
reply=$(curl -v -g -L -b "$cookie_jar" -c "$cookie_jar" -G --data-urlencode q="$terms" --data-urlencode fckh="$fckh" https://mp3skull.is/search_db.php) || err 'Did not get a response from mp3skull for that search'
put reply | grep -qi 'your search session has expired' && err 'Could not search (bad session id)'
results=$(put reply | parse_mp3_results)
[ -n "$results" ] || err 'Could not find any search results'
selected=$(put results | select_mp3_results) || exit
[ -n "$selected" ] || err 'No results selected'
mkdir -p -- "$music_dir"
cd -- "$music_dir"
while [ -n "$selected" ]; do
url=${selected%%|*}
selected=${selected#*|}
put url
launch_download "$url" &
[ "$selected" = "$url" ] && break
done
wait
@ScoreUnder
Copy link
Author

Description

This will make a search on mp3skull.is, put the results into a table, and then let you select the ones you want (with support for selecting multiple items) and download them directly to your music folder.

Notes:

There seem to be a few anti-automation measures on the site. Perhaps this won't work when they get wind of it.
This probably doesn't have very good error handling. I tried.

Requires:

  • curl for downloads
  • awk for parsing (tested in gawk and mawk)
  • zenity for the gui
  • xdg-user-dirs (optional) to find out where your music folder is

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment