Compare commits

..

12 commits
stable ... dev

5 changed files with 194 additions and 132 deletions

View file

@ -11,7 +11,7 @@
- Create install scripts/guides (WIP)
- Migrate from Bash to a POSIX-compliant shell
- Add Cover, and other metadata to vorbis tag (Almost done)
- Lyrics download (WIP)
- Lyrics download (Almost done)
- Implement search & download for playlists, albums, and artists (WIP)
- Support downloading multiple search results
- Allow users to choose audio quality (currently defaults to LOSSLESS)

View file

@ -1,8 +1,8 @@
# Maintainer: Medvidek77 <medvidek77@tuta.io>
pkgname=tidler
pkgver=0.3.0
pkgrel=3
pkgver=0.3.1
pkgrel=1
pkgdesc="Tidal music downloader based on the hifi-tui API"
arch=('any')
url="https://git.medvidek77.tech/Medvidek77/tidler"

View file

@ -1,8 +1,8 @@
# Maintainer: Medvidek77 <medvidek77@tuta.io>
pkgname=tidler
pkgver=0.3.0
pkgrel=3
pkgver=0.3.2-beta2
pkgrel=1
pkgdesc="Tidal music downloader based on the hifi-tui API"
arch=('any')
url="https://git.medvidek77.tech/Medvidek77/tidler"

View file

@ -1,55 +1,56 @@
#!/bin/bash
#!/usr/bin/env bash
. tidler.conf # Load ENVs from config file
version="0.3.0"
version="0.3.2-beta2"
if [ -n "$PROXY_URL" ]; then
proxy_url="$PROXY_URL"
proxy_url="$PROXY_URL"
else
proxy_url="https://hifi-04ed2aaea09a.herokuapp.com" # Default value
proxy_url="https://hifi-04ed2aaea09a.herokuapp.com" # Default value
fi
if [ -n "$QUALITY" ]; then
if [ "$QUALITY" = "LOSSLESS" -o "$QUALITY" = "HI_RES" ]; then
quality="$QUALITY"
else
echo "Bad QUALITY option. Only allowed are \"LOSSLESS\", \"HI_RES\"."
echo "Using default value..."
if [ "$QUALITY" = "LOSSLESS" -o "$QUALITY" = "HI_RES" ]; then
quality="$QUALITY"
else
echo "Bad QUALITY option. Only allowed are \"LOSSLESS\", \"HI_RES\"."
echo "Using default value..."
quality="LOSSLESS" # Default value
fi
quality="LOSSLESS" # Default value
fi
else
quality="LOSSLESS" # Default value
quality="LOSSLESS" # Default value
fi
if [ -n "$COVER_RESOLUTION" ]; then
if [ "$COVER_RESOLUTION" = "1280" -o "$COVER_RESOLUTION" = "640" -o "$COVER_RESOLUTION" = "80" ]; then
cover_resolution="$COVER_RESOLUTION"
else
echo "Bad COVER_RESOLUTION option. Only allowed are \"1280\", \"640\", \"80\"."
echo "Using default value..."
if [ "$COVER_RESOLUTION" = "1280" -o "$COVER_RESOLUTION" = "640" -o "$COVER_RESOLUTION" = "80" ]; then
cover_resolution="$COVER_RESOLUTION"
else
echo "Bad COVER_RESOLUTION option. Only allowed are \"1280\", \"640\", \"80\"."
echo "Using default value..."
cover_resolution="1280" # Default value
fi
cover_resolution="1280" # Default value
fi
else
cover_resolution="1280" # Default value
cover_resolution="1280" # Default value
fi
if [ -n "$MAX_ATTEMPTS" ]; then
if [ "$MAX_ATTEMPTS" -ge 1 -a "$MAX_ATTEMPTS" -le 100 ]; then
max_attempts="$MAX_ATTEMPTS"
else
echo "Bad MAX_ATTEMPTS option. Allowed are numbers from 1 to 100."
echo "Using default value..."
if [ "$MAX_ATTEMPTS" -ge 1 -a "$MAX_ATTEMPTS" -le 100 ]; then
max_attempts="$MAX_ATTEMPTS"
else
echo "Bad MAX_ATTEMPTS option. Allowed are numbers from 1 to 100."
echo "Using default value..."
max_attempts="10" # Default value
fi
max_attempts="10" # Default value
fi
else
max_attempts="10" # Default value
max_attempts="10" # Default value
fi
downloadTrack() {
if [ "$#" -ge 1 ]; then
echo "Downloading track with ID: $1"
@ -59,39 +60,56 @@ downloadTrack() {
read -r id
fi
if [ "$#" -ge 2 ]; then
album_dir="$2"
else
album_dir=""
fi
attempt_num=1
success=false
lrc_success=false
while [ $attempt_num -le $max_attempts ]; do
json_data=$(curl -# "$proxy_url/track/?id=$id&quality=$quality")
if [ $? -eq 0 ]; then
track_name=$(echo "$json_data" | jq -r '.[0].title // empty')
if [ -n "$track_name" ]; then
artist_name=$(echo "$json_data" | jq -r '.[0].artist.name // empty')
if [ -n "$artist_name" ]; then
album_name=$(echo "$json_data" | jq -r '.[0].album.title // empty')
if [ -n "$album_name" ]; then
url=$(echo "$json_data" | jq -r '.[-1].OriginalTrackUrl // empty')
if [ -n "$url" ]; then
cover_data=$(curl -# "$proxy_url/cover/?id=$id")
cover_url=$(echo "$cover_data" | jq -r '.[]["1280"] // empty')
if [ -n "$cover_url" ]; then
track_number=$(echo "$json_data" | jq -r '.[0].trackNumber')
filename="$track_name.flac"
cover_name="cover.png"
success=true
if [ -n "$cover_url" ]; then
date_data=$(echo "$json_data" | jq -r '.[0].streamStartDate // empty' )
date=$(expr substr "$date_data" 1 10)
year=$(expr substr "$date_data" 1 4)
if [ -n "$year" ]; then
track_number=$(echo "$json_data" | jq -r '.[0].trackNumber')
filename="$track_name.flac"
cover_name="tidler_temp_cover_$track_name.png"
success=true
lyrics_data=$(curl -# "$proxy_url/lyrics/?id=$id")
if [ $? -eq 0 ]; then
timed_lyrics=$(echo "$lyrics_data" | jq -r '.[0].subtitles')
if [ -n "$timed_lyrics" ]; then
lrc_success=true
elif [ "$timed_lyrics" == "null" ]; then
echo "Lyrics not found"
fi
fi
fi
break
fi
fi
@ -100,51 +118,58 @@ downloadTrack() {
fi
fi
if [ "$success" = false ]; then
echo "Attempt $attempt_num failed. Retrying..."
((attempt_num++))
sleep "1.$(tr -cd 0-9 </dev/urandom | head -c 5)"
sleep "1.$(tr -cd 0-9 < /dev/urandom | head -c 5)"
fi
done
if [ "$success" = false ]; then
echo "Failed to download after $max_attempts attempts."
exit 1
fi
if [ -n "$DOWNLOADS_DIR" ]; then
download_dir="$DOWNLOADS_DIR"
else
echo "Using current path..."
download_dir="$(pwd)"
fi
if [ -z "$album_dir" ]; then
final_path="$download_dir"
else
final_path="$download_dir/$album_dir"
fi
final_path="$download_dir/$artist_name/$album_name"
mkdir -p "$final_path"
curl -# "$url" -o "$final_path/$filename"
curl -# "$cover_url" -o "$final_path/$cover_name"
curl -# "$cover_url" -o "/tmp/$cover_name"
# Metadata
metaflac \
--set-tag="NAME=$track_name" \
--set-tag="ARTIST=$artist_name" \
--set-tag="ALBUM=$album_name" \
--set-tag="TRACKNUMBER=$track_number" \
--import-picture-from="$final_path/$cover_name" \
${lrc_success:+--set-tag="LYRICS=$timed_lyrics"} \
--set-tag="DATE=$date" \
--set-tag="YEAR=$year" \
--import-picture-from="/tmp/$cover_name" \
"$final_path/$filename"
rm "/tmp/$cover_name"
}
searchTrack() {
if [ "$#" -ge 1 ]; then
track_name="$1"
track_name="$1"
else
echo "Enter track name:"
read -r track_name
echo "Enter track name:"
read -r track_name
fi
track_name=$(echo "$track_name" | sed 's/ /%20/g')
tracks=$(curl -# "$proxy_url/search/?s=$track_name" | jq -r '.items[] | "\(.id) - \(.title) by \(.artist.name)"')
@ -157,19 +182,27 @@ searchTrack() {
if [ "${#tracks_list[@]}" -eq 1 ]; then
echo "No tracks found :("
exit 1
fi
else
i=0
while [ "$i" -lt "${#tracks_list[@]}" ]; do
echo "$((i + 1))) ${tracks_list["$i"]}"
i=$(( i + 1 ))
done
read -a inp
echo "${inp[0]}"
i=0
while [ "$i" -lt "${#inp[@]}" ]; do
inp2=$(("${inp[i]}" - 1))
if [ "$inp2" -ge 0 ] && [ "$inp2" -lt "${#tracks_list[@]}" ]; then
track_id=$(echo "${tracks_list["$inp2"]}" | awk -F ' - ' '{print $1}')
downloadTrack "$track_id"
else
echo "Invalid selection. Please try again."
PS3="Please select a track: "
select t in "${tracks_list[@]}"; do
if [ -n "$t" ]; then
track_id=$(echo "$t" | awk -F ' - ' '{print $1}')
echo "You selected: $t"
downloadTrack "$track_id"
break
else
echo "Invalid selection. Please try again."
fi
done
fi
i=$(( i + 1 ))
done
fi
}
@ -244,18 +277,27 @@ searchAlbum() {
((attempt_num++))
sleep "1.$(tr -cd 0-9 </dev/urandom | head -c 5)"
else
PS3="Please select an album: "
select t in "${albums_list[@]}"; do
if [ -n "$t" ]; then
album_id=$(echo "$t" | awk -F ': ' '{print $1}')
echo "You selected: $t"
downloadAlbum "$album_id"
success=true
break
else
echo "Invalid selection. Please try again."
fi
i=0
while [ "$i" -lt "${#albums_list[@]}" ]; do
echo "$((i + 1))) ${albums_list["$i"]}"
i=$(( i + 1 ))
done
read -a inp
echo "${inp[0]}"
i=0
while [ "$i" -lt "${#inp[@]}" ]; do
inp2=$(("${inp[i]}" - 1))
if [ "$inp2" -ge 0 ] && [ "$inp2" -lt "${#albums_list[@]}" ]; then
album_id=$(echo "${albums_list["$inp2"]}" | awk -F ': ' '{print $1}')
downloadAlbum "$album_id"
else
echo "Invalid selection. Please try again."
fi
i=$(( i + 1 ))
done
success=true
if [ "$success" = true ]; then
break
fi
@ -268,57 +310,77 @@ searchAlbum() {
fi
}
#searchArtist() {
#}
#downloadArtist() {
#}
if [ "$1" = "search" ]; then
if [ "$#" -ge 2 ]; then
shift
jsw="$*"
searchTrack "$jsw"
else
searchTrack
fi
if [ "$#" -ge 2 ]; then
shift
jsw="$*"
searchTrack "$jsw"
else
searchTrack
fi
elif [ "$1" = "download" ]; then
if [ "$#" -ge 2 ]; then
downloadTrack "$2"
else
downloadTrack
fi
if [ "$#" -ge 2 ]; then
downloadTrack "$2"
else
downloadTrack
fi
elif [ "$1" = "album" ]; then
if [ "$#" -ge 2 ]; then
shift
jsw="$*"
searchAlbum "$jsw"
else
searchAlbum
fi
if [ "$#" -ge 2 ]; then
shift
jsw="$*"
searchAlbum "$jsw"
else
searchAlbum
fi
elif [ "$1" == "version" ]; then
echo "TiDLer $version by Medvidek77"
echo "TiDLer $version by Medvidek77"
elif [ "$1" = "help" ]; then
echo "<MODE>"
echo ""
echo "If a valid parameter is provided, the corresponding function executes. Otherwise, TiDLer enters INTERACTIVE mode!"
echo ""
echo "<COMMANDS>"
echo ""
echo "search {track_name}-optional -> search any song"
echo ""
echo "download {song_id}-optional -> download any song"
echo ""
echo "album {album_name}-optional -> search and download any album"
echo ""
echo "version -> print TiDLer version"
echo ""
echo "help -> print this message and exit"
echo "<MODE>"
echo ""
echo "If a valid parameter is provided, the corresponding function executes. Otherwise, TiDLer enters INTERACTIVE mode!"
echo ""
echo "<COMMANDS>"
echo ""
echo "search {track_name}-optional -> search any song"
echo ""
echo "download {song_id}-optional -> download any song"
echo ""
echo "album {album_name}-optional -> search and download any album"
echo ""
echo "version -> print TiDLer version"
echo ""
echo "help -> print this message and exit"
else
echo "### Choose function! (Enter number) ###"
echo ""
echo "1. Download single track with ID"
echo ""
echo "2. Search single track with text"
echo ""
echo "3. Search and download whole album with text"
read option
echo "### Choose function! (Enter number) ###"
echo ""
echo "1. Download single track with ID"
echo ""
echo "2. Search single track with text"
echo ""
echo "3. Search and download whole album with text"
read option
if [ "$option" -eq 1 ]; then
downloadTrack
elif [ "$option" -eq 2 ]; then
searchTrack
elif [ "$option" -eq 3 ]; then
searchAlbum
fi
fi
if [ "$option" -eq 1 ]; then
downloadTrack
elif [ "$option" -eq 2 ]; then
@ -326,4 +388,4 @@ else
elif [ "$option" -eq 3 ]; then
searchAlbum
fi
fi
fi

View file

@ -12,4 +12,4 @@ QUALITY="LOSSLESS"
COVER_RESOLUTION="1280"
# If there is any problem with the API, Tidler will attempt to download the track again -> possible values are "1" to "100"
MAX_ATTEMPTS="10"
MAX_ATTEMPTS="15"