improved speed, added local data lists, some cleaning
This commit is contained in:
64
src/main.sh
64
src/main.sh
@@ -3,10 +3,10 @@
|
|||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
# The user interface of this application is composed out of the following
|
# The user interface of this application is composed out of the following
|
||||||
# views.
|
# views:
|
||||||
# - VIEW_ARTIST: Show all release group of an artist
|
# - VIEW_ARTIST: Show all release group of an artist
|
||||||
# - VIEW_RELEASEGROUP: Show all releases within a release group
|
# - VIEW_RELEASEGROUP: Show all releases within a release group
|
||||||
# - VIEW_RELEASE: Show track list of release
|
# - VIEW_RELEASE: Show track list of a release
|
||||||
# - VIEW_SEARCH_ARTIST: Interface to search artists on MusicBrainz
|
# - VIEW_SEARCH_ARTIST: Interface to search artists on MusicBrainz
|
||||||
# - VIEW_SEARCH_ALBUM: Interface to search albums (release groups) on MusicBrainz
|
# - VIEW_SEARCH_ALBUM: Interface to search albums (release groups) on MusicBrainz
|
||||||
# - VIEW_LIST_ARTISTS: Presentation of all artists in the local database
|
# - VIEW_LIST_ARTISTS: Presentation of all artists in the local database
|
||||||
@@ -16,7 +16,7 @@ set -eu
|
|||||||
# - VIEW_QUIT: Exiting view, to terminate the application
|
# - VIEW_QUIT: Exiting view, to terminate the application
|
||||||
#
|
#
|
||||||
# All views but the last three are handled within a single fzf instance. The
|
# All views but the last three are handled within a single fzf instance. The
|
||||||
# views VIEW_SELECT_ARTIST, and VIEW_PLAYLIST run each in a separate fzf
|
# views VIEW_SELECT_ARTIST and VIEW_PLAYLIST run each in a separate fzf
|
||||||
# instance. The last view (VIEW_QUIT) does nothing but terminate the
|
# instance. The last view (VIEW_QUIT) does nothing but terminate the
|
||||||
# application.
|
# application.
|
||||||
#
|
#
|
||||||
@@ -26,7 +26,7 @@ set -eu
|
|||||||
# the query string can be written.
|
# the query string can be written.
|
||||||
#
|
#
|
||||||
# All views and modes are referred to by the following constants. The values
|
# All views and modes are referred to by the following constants. The values
|
||||||
# are arbitrary but distinct.
|
# are arbitrary but must be distinct.
|
||||||
VIEW_ARTIST="artist"
|
VIEW_ARTIST="artist"
|
||||||
VIEW_RELEASEGROUP="rg"
|
VIEW_RELEASEGROUP="rg"
|
||||||
VIEW_RELEASE="release"
|
VIEW_RELEASE="release"
|
||||||
@@ -56,7 +56,7 @@ MODE_INSERT="show"
|
|||||||
# Load playlist tools
|
# Load playlist tools
|
||||||
. "sh/playlist.sh"
|
. "sh/playlist.sh"
|
||||||
|
|
||||||
# Load MusicBrainz and Discogs methods
|
# Load MusicBrainz, Discogs, and wiki methods
|
||||||
. "sh/api.sh"
|
. "sh/api.sh"
|
||||||
|
|
||||||
# Load mpv methods
|
# Load mpv methods
|
||||||
@@ -313,6 +313,18 @@ case "${1:-}" in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
# Load configuration
|
||||||
|
. "sh/config.sh"
|
||||||
|
|
||||||
|
# Load theme
|
||||||
|
. "sh/theme.sh"
|
||||||
|
|
||||||
|
# Load tools
|
||||||
|
. "sh/tools.sh"
|
||||||
|
|
||||||
|
# Load AWK scripts
|
||||||
|
. "sh/awk.sh"
|
||||||
|
|
||||||
# Non-interactive user commands intended to the user. These commands do not
|
# Non-interactive user commands intended to the user. These commands do not
|
||||||
# require temporary files, fzf, nor the mpv instance.
|
# require temporary files, fzf, nor the mpv instance.
|
||||||
case "${1:-}" in
|
case "${1:-}" in
|
||||||
@@ -332,7 +344,7 @@ case "${1:-}" in
|
|||||||
fi
|
fi
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
"--reload")
|
"--reload-database")
|
||||||
# Reload database of local music
|
# Reload database of local music
|
||||||
#
|
#
|
||||||
# @argument $2: path
|
# @argument $2: path
|
||||||
@@ -343,7 +355,7 @@ case "${1:-}" in
|
|||||||
[ ! "${2:-}" ] && err "Path to decorated music is missing." && exit 1
|
[ ! "${2:-}" ] && err "Path to decorated music is missing." && exit 1
|
||||||
[ ! -d "$2" ] && err "Path does not point to a directory." && exit 1
|
[ ! -d "$2" ] && err "Path does not point to a directory." && exit 1
|
||||||
info "Reloading information of local music directory $2"
|
info "Reloading information of local music directory $2"
|
||||||
load_local "$2" || err "Failed to load local data"
|
reloaddb "$2" || err "Failed to load local data"
|
||||||
info "Done"
|
info "Done"
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
@@ -356,27 +368,18 @@ GENERAL OPTIONS:
|
|||||||
--help Show this help and exit.
|
--help Show this help and exit.
|
||||||
--artists Default options, list artists of local music
|
--artists Default options, list artists of local music
|
||||||
--albums List albums of local music
|
--albums List albums of local music
|
||||||
--search-artist [<query>] Search artist on MusicBrainz
|
--search-artist Search artist on MusicBrainz
|
||||||
--search-album [<query>] Search album on MusicBrainz
|
--search-album Search album on MusicBrainz
|
||||||
--artist <mbid> List release groups of given artist <mbid>
|
--artist <mbid> List release groups of given artist <mbid>
|
||||||
--releasegroup <mbid> List releases in given release group <mbid>
|
--releasegroup <mbid> List releases in given release group <mbid>
|
||||||
--release <mbid> Show release given by <mbid>
|
--release <mbid> Show release given by <mbid>
|
||||||
--ni-search-artist [<query>] Non-interactive search on MusicBrainz
|
|
||||||
--ni-search-album [<query>] Non-interactive search on MusicBrainz
|
|
||||||
|
|
||||||
MANAGE LOCAL MUSIC:
|
MANAGE LOCAL MUSIC:
|
||||||
--decorate <path> Decorate directory containing a tagged release
|
--decorate <path> Decorate directory containing a tagged release
|
||||||
--reload <path> Populate database with decorated local music from <path>
|
--reload-database <path> Populate database with decorated local music from <path>
|
||||||
EOF
|
EOF
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
"--refresh-view")
|
|
||||||
# Recompute main views
|
|
||||||
#
|
|
||||||
# With this method, the content for the views VIEW_LIST_ARTISTS and VIEW_LIST_ALBUMS are recomputed.
|
|
||||||
precompute_view
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# Interactive user commands
|
# Interactive user commands
|
||||||
@@ -428,38 +431,29 @@ case "${1:-}" in
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
# Start application:
|
# Start application:
|
||||||
# - load configuration
|
|
||||||
# - load and export theme
|
|
||||||
# - load and export preset filters
|
# - load and export preset filters
|
||||||
# - load and export keys
|
# - load and export keys
|
||||||
# - load and export tools
|
|
||||||
# - load and export awk scripts
|
|
||||||
# - set title
|
# - set title
|
||||||
|
# - check for missing data from MusicBrainz
|
||||||
|
# - precompute main views
|
||||||
# - get temporary directory for temporary files
|
# - get temporary directory for temporary files
|
||||||
# - start mpv daemon
|
# - start mpv daemon
|
||||||
# - enter main loop and start fzf
|
# - enter main loop and start fzf
|
||||||
|
|
||||||
# Load configuration
|
|
||||||
. "sh/config.sh"
|
|
||||||
|
|
||||||
# Load theme
|
|
||||||
. "sh/theme.sh"
|
|
||||||
|
|
||||||
# Load filters
|
# Load filters
|
||||||
. "sh/filter.sh"
|
. "sh/filter.sh"
|
||||||
|
|
||||||
# Load keys
|
# Load keys
|
||||||
. "sh/keys.sh"
|
. "sh/keys.sh"
|
||||||
|
|
||||||
# Load tools
|
|
||||||
. "sh/tools.sh"
|
|
||||||
|
|
||||||
# Load AWK scripts
|
|
||||||
. "sh/awk.sh"
|
|
||||||
|
|
||||||
# Set window title
|
# Set window title
|
||||||
printf '\033]0;%s\007' "$WINDOW_TITLE"
|
printf '\033]0;%s\007' "$WINDOW_TITLE"
|
||||||
|
|
||||||
|
# Check if the required json files are present
|
||||||
|
local_files_present || load_missing_files
|
||||||
|
# Generate views
|
||||||
|
precompute_views
|
||||||
|
|
||||||
# Generate filenames for temporary files
|
# Generate filenames for temporary files
|
||||||
tmpdir=$(mktemp -d)
|
tmpdir=$(mktemp -d)
|
||||||
LOCKFILE="$tmpdir/lock"
|
LOCKFILE="$tmpdir/lock"
|
||||||
|
@@ -1,7 +1,12 @@
|
|||||||
MB_MAX_RETRIES=10
|
if [ ! "${API_LOADED:-}" ]; then
|
||||||
MB_BROWSE_STEPS=100
|
MB_MAX_RETRIES=10
|
||||||
USER_AGENT="$APP_NAME/$APP_VERSION ($APP_WEBSITE)"
|
MB_BROWSE_STEPS=100
|
||||||
SLEEP_ON_ERROR=1
|
USER_AGENT="$APP_NAME/$APP_VERSION ($APP_WEBSITE)"
|
||||||
|
SLEEP_ON_ERROR=1
|
||||||
|
export MB_MAX_RETRIES MB_BROWSE_STEPS USER_AGENT SLEEP_ON_ERROR
|
||||||
|
|
||||||
|
export API_LOADED=1
|
||||||
|
fi
|
||||||
|
|
||||||
__api_mb() {
|
__api_mb() {
|
||||||
tmpout=$(mktemp)
|
tmpout=$(mktemp)
|
||||||
@@ -78,16 +83,18 @@ __api_mb() {
|
|||||||
"https://musicbrainz.org/ws/2/release-group"
|
"https://musicbrainz.org/ws/2/release-group"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
if ! $JQ -e '.error' "$tmpout" >/dev/null 2>/dev/stdout; then
|
errormsg=$($JQ -e '.error // ""' "$tmpout")
|
||||||
|
if [ "$errormsg" ]; then
|
||||||
|
err "Failed to fetch MusicBrainz data for $1 $2: $errormsg"
|
||||||
|
sleep "$SLEEP_ON_ERROR"
|
||||||
|
else
|
||||||
cat "$tmpout"
|
cat "$tmpout"
|
||||||
rm -f "$tmpout"
|
rm -f "$tmpout"
|
||||||
return 0
|
return 0
|
||||||
else
|
|
||||||
sleep "$SLEEP_ON_ERROR"
|
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
rm -f "$tmpout"
|
rm -f "$tmpout"
|
||||||
err "Failed to fetch MusicBrainz data for $1 $2"
|
err "Failed to fetch MusicBrainz data for $1 $2 (not retrying anymore...)"
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
114
src/sh/cache.sh
114
src/sh/cache.sh
@@ -6,25 +6,38 @@
|
|||||||
# ./releasegroup/radix(uuid)/musicbrainz.json # Release group information
|
# ./releasegroup/radix(uuid)/musicbrainz.json # Release group information
|
||||||
# ./releasegroup/radix(uuid)/releases.json # List of all releases in release group
|
# ./releasegroup/radix(uuid)/releases.json # List of all releases in release group
|
||||||
# ./release/radix(uuid)/musicbrainz.json # Release information with tracklist etc.
|
# ./release/radix(uuid)/musicbrainz.json # Release information with tracklist etc.
|
||||||
CACHEDIR="$HOME/.cache/$APP_NAME"
|
|
||||||
TYPE_ARTIST="artist"
|
|
||||||
TYPE_RELEASEGROUP="releasegroup"
|
|
||||||
TYPE_RELEASE="release"
|
|
||||||
|
|
||||||
artist_filename="musicbrainz.json"
|
if [ ! "${CACHE_LOADED:-}" ]; then
|
||||||
artist_releasegroups_filename="releasegroups.json"
|
CACHEDIR="$HOME/.cache/$APP_NAME"
|
||||||
artist_discogs_filename="discogs.json"
|
TYPE_ARTIST="artist"
|
||||||
artist_wikidata_filename="wikidata.json"
|
TYPE_RELEASEGROUP="releasegroup"
|
||||||
artist_enwikipedia_filename="enwikipedia.json"
|
TYPE_RELEASE="release"
|
||||||
releasegroup_filename="musicbrainz.json"
|
ARTIST_FILENAME="musicbrainz.json"
|
||||||
releasegroup_releases_filename="releases.json"
|
ARTIST_RELEASEROUPS_FILENAME="releasegroups.json"
|
||||||
release_filename="musicbrainz.json"
|
ARTIST_DISCOGS_FILENAME="discogs.json"
|
||||||
|
ARTIST_WIKIDATA_FILENAME="wikidata.json"
|
||||||
|
ARTIST_ENWIKIPEDIA_FILENAME="enwikipedia.json"
|
||||||
|
RELEASEGROUP_FILENAME="musicbrainz.json"
|
||||||
|
RELEASEGROUP_RELEASES_FILENAME="releases.json"
|
||||||
|
RELEASE_FILENAME="musicbrainz.json"
|
||||||
|
export CACHEDIR TYPE_ARTIST TYPE_RELEASEGROUP TYPE_RELEASE ARTIST_FILENAME \
|
||||||
|
ARTIST_RELEASEROUPS_FILENAME ARTIST_DISCOGS_FILENAME \
|
||||||
|
ARTIST_WIKIDATA_FILENAME ARTIST_ENWIKIPEDIA_FILENAME \
|
||||||
|
RELEASEGROUP_FILENAME RELEASEGROUP_RELEASES_FILENAME RELEASE_FILENAME
|
||||||
|
|
||||||
|
export CACHE_LOADED=1
|
||||||
|
fi
|
||||||
|
|
||||||
# Radix transform directory name
|
# Radix transform directory name
|
||||||
__radix() {
|
__radix() {
|
||||||
echo "$1" | awk -F "" '{ print $1$2$3$4"/"$5$6$7$8"/"$0 }'
|
echo "$1" | awk -F "" '{ print $1$2$3$4"/"$5$6$7$8"/"$0 }'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Radix transform directory names from stdin
|
||||||
|
__radix_batch() {
|
||||||
|
cat | awk -F "" '{ print $1$2$3$4"/"$5$6$7$8"/"$0 }'
|
||||||
|
}
|
||||||
|
|
||||||
# Super wrapper
|
# Super wrapper
|
||||||
# argument $1: type
|
# argument $1: type
|
||||||
# argument $2: MusicBrainz ID
|
# argument $2: MusicBrainz ID
|
||||||
@@ -50,87 +63,87 @@ __put_json() {
|
|||||||
|
|
||||||
## Artist
|
## Artist
|
||||||
cache_get_artist() {
|
cache_get_artist() {
|
||||||
__get_json "$TYPE_ARTIST" "$1" "$artist_filename"
|
__get_json "$TYPE_ARTIST" "$1" "$ARTIST_FILENAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_get_artist_releasegroups() {
|
cache_get_artist_releasegroups() {
|
||||||
__get_json "$TYPE_ARTIST" "$1" "$artist_releasegroups_filename"
|
__get_json "$TYPE_ARTIST" "$1" "$ARTIST_RELEASEROUPS_FILENAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_get_artist_discogs() {
|
cache_get_artist_discogs() {
|
||||||
__get_json "$TYPE_ARTIST" "$1" "$artist_discogs_filename"
|
__get_json "$TYPE_ARTIST" "$1" "$ARTIST_DISCOGS_FILENAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_get_artist_enwikipedia() {
|
cache_get_artist_enwikipedia() {
|
||||||
__get_json "$TYPE_ARTIST" "$1" "$artist_enwikipedia_filename"
|
__get_json "$TYPE_ARTIST" "$1" "$ARTIST_ENWIKIPEDIA_FILENAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_get_artist_wikidata() {
|
cache_get_artist_wikidata() {
|
||||||
__get_json "$TYPE_ARTIST" "$1" "$artist_wikidata_filename"
|
__get_json "$TYPE_ARTIST" "$1" "$ARTIST_WIKIDATA_FILENAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_put_artist() {
|
cache_put_artist() {
|
||||||
cat | __put_json "$TYPE_ARTIST" "$1" "$artist_filename"
|
cat | __put_json "$TYPE_ARTIST" "$1" "$ARTIST_FILENAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_put_artist_releasegroups() {
|
cache_put_artist_releasegroups() {
|
||||||
cat | __put_json "$TYPE_ARTIST" "$1" "$artist_releasegroups_filename"
|
cat | __put_json "$TYPE_ARTIST" "$1" "$ARTIST_RELEASEROUPS_FILENAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_append_artist_releasegroups() {
|
cache_append_artist_releasegroups() {
|
||||||
tmpf=$(mktemp)
|
tmpf=$(mktemp)
|
||||||
cat >"$tmpf"
|
cat >"$tmpf"
|
||||||
updated=$(mktemp)
|
updated=$(mktemp)
|
||||||
f="$CACHEDIR/$TYPE_ARTIST/$(__radix "$1")/$artist_releasegroups_filename"
|
f="$CACHEDIR/$TYPE_ARTIST/$(__radix "$1")/$ARTIST_RELEASEROUPS_FILENAME"
|
||||||
$JQ --slurpfile n "$tmpf" '."release-groups" += ($n[0]|."release-groups")' "$f" >"$updated" && mv "$updated" "$f"
|
$JQ --slurpfile n "$tmpf" '."release-groups" += ($n[0]|."release-groups")' "$f" >"$updated" && mv "$updated" "$f"
|
||||||
rm -f "$tmpf"
|
rm -f "$tmpf"
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_put_artist_discogs() {
|
cache_put_artist_discogs() {
|
||||||
cat | __put_json "$TYPE_ARTIST" "$1" "$artist_discogs_filename"
|
cat | __put_json "$TYPE_ARTIST" "$1" "$ARTIST_DISCOGS_FILENAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_put_artist_enwikipedia() {
|
cache_put_artist_enwikipedia() {
|
||||||
cat | __put_json "$TYPE_ARTIST" "$1" "$artist_enwikipedia_filename"
|
cat | __put_json "$TYPE_ARTIST" "$1" "$ARTIST_ENWIKIPEDIA_FILENAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_put_artist_wikidata() {
|
cache_put_artist_wikidata() {
|
||||||
cat | __put_json "$TYPE_ARTIST" "$1" "$artist_wikidata_filename"
|
cat | __put_json "$TYPE_ARTIST" "$1" "$ARTIST_WIKIDATA_FILENAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
## Release group
|
## Release group
|
||||||
cache_get_releasegroup() {
|
cache_get_releasegroup() {
|
||||||
__get_json "$TYPE_RELEASEGROUP" "$1" "$releasegroup_filename"
|
__get_json "$TYPE_RELEASEGROUP" "$1" "$RELEASEGROUP_FILENAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_get_releasegroup_releases() {
|
cache_get_releasegroup_releases() {
|
||||||
__get_json "$TYPE_RELEASEGROUP" "$1" "$releasegroup_releases_filename"
|
__get_json "$TYPE_RELEASEGROUP" "$1" "$RELEASEGROUP_RELEASES_FILENAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_put_releasegroup() {
|
cache_put_releasegroup() {
|
||||||
cat | __put_json "$TYPE_RELEASEGROUP" "$1" "$releasegroup_filename"
|
cat | __put_json "$TYPE_RELEASEGROUP" "$1" "$RELEASEGROUP_FILENAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_put_releasegroup_releases() {
|
cache_put_releasegroup_releases() {
|
||||||
cat | __put_json "$TYPE_RELEASEGROUP" "$1" "$releasegroup_releases_filename"
|
cat | __put_json "$TYPE_RELEASEGROUP" "$1" "$RELEASEGROUP_RELEASES_FILENAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_append_releasegroup_releases() {
|
cache_append_releasegroup_releases() {
|
||||||
tmpf=$(mktemp)
|
tmpf=$(mktemp)
|
||||||
cat >"$tmpf"
|
cat >"$tmpf"
|
||||||
updated=$(mktemp)
|
updated=$(mktemp)
|
||||||
f="$CACHEDIR/$TYPE_RELEASEGROUP/$(__radix "$1")/$releasegroup_releases_filename"
|
f="$CACHEDIR/$TYPE_RELEASEGROUP/$(__radix "$1")/$RELEASEGROUP_RELEASES_FILENAME"
|
||||||
$JQ --slurpfile n "$tmpf" '."releases" += ($n[0]|."releases")' "$f" >"$updated" && mv "$updated" "$f"
|
$JQ --slurpfile n "$tmpf" '."releases" += ($n[0]|."releases")' "$f" >"$updated" && mv "$updated" "$f"
|
||||||
rm -f "$tmpf"
|
rm -f "$tmpf"
|
||||||
}
|
}
|
||||||
|
|
||||||
## Release
|
## Release
|
||||||
cache_get_release() {
|
cache_get_release() {
|
||||||
__get_json "$TYPE_RELEASE" "$1" "$release_filename"
|
__get_json "$TYPE_RELEASE" "$1" "$RELEASE_FILENAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_put_release() {
|
cache_put_release() {
|
||||||
cat | __put_json "$TYPE_RELEASE" "$1" "$release_filename"
|
cat | __put_json "$TYPE_RELEASE" "$1" "$RELEASE_FILENAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
## Cache deletion
|
## Cache deletion
|
||||||
@@ -144,18 +157,35 @@ cache_delete_artist() {
|
|||||||
# argument $2: MusicBrainz ID
|
# argument $2: MusicBrainz ID
|
||||||
in_cache() {
|
in_cache() {
|
||||||
case "$1" in
|
case "$1" in
|
||||||
"$TYPE_ARTIST")
|
"$TYPE_ARTIST") fn="$ARTIST_FILENAME" ;;
|
||||||
fn="$artist_filename"
|
"$TYPE_RELEASEGROUP") fn="$RELEASEGROUP_FILENAME" ;;
|
||||||
;;
|
"$TYPE_RELEASE") fn="$RELEASE_FILENAME" ;;
|
||||||
"$TYPE_RELEASEGROUP")
|
*) return 1 ;;
|
||||||
fn="$releasegroup_filename"
|
|
||||||
;;
|
|
||||||
"$TYPE_RELEASE")
|
|
||||||
fn="$release_filename"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
[ "$(__get_json "$1" "$2" "$fn")" ] && return 0 || return 1
|
[ "$(__get_json "$1" "$2" "$fn")" ] && return 0 || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Print all cache paths to the files specified by their IDs
|
||||||
|
#
|
||||||
|
# @argument $1: type
|
||||||
|
#
|
||||||
|
# This method reads from stdin any number of MusicBrainz IDs of objects of the
|
||||||
|
# specified type, and prints the file pahts.
|
||||||
|
cache_get_file_batch() {
|
||||||
|
case "$1" in
|
||||||
|
"$TYPE_ARTIST") fn="$ARTIST_FILENAME" ;;
|
||||||
|
"$TYPE_RELEASEGROUP") fn="$RELEASEGROUP_FILENAME" ;;
|
||||||
|
"$TYPE_RELEASE") fn="$RELEASE_FILENAME" ;;
|
||||||
|
*) return 1 ;;
|
||||||
|
esac
|
||||||
|
cat |
|
||||||
|
__radix_batch |
|
||||||
|
awk -v dir="$CACHEDIR/$1/" -v f="/$fn" '{ print dir $0 f }'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Print MusicBrainz ID associated to the file paths
|
||||||
|
#
|
||||||
|
# This reads from stdin any number of paths (one per line)
|
||||||
|
cache_mbid_from_path_batch() {
|
||||||
|
cat | awk -F "/" '{ print $(NF-1) }'
|
||||||
|
}
|
||||||
|
@@ -1,5 +1,10 @@
|
|||||||
# Application information
|
# Application information
|
||||||
APP_NAME="fuzic"
|
if [ ! "${INFO_LOADED:-}" ]; then
|
||||||
APP_VERSION="0.1"
|
APP_NAME="fuzic"
|
||||||
APP_WEBSITE="https://git.indyfac.ch/amin/fuzic"
|
APP_VERSION="0.1"
|
||||||
WINDOW_TITLE="🔎🎶 $APP_NAME | a simple music finder and player"
|
APP_WEBSITE="https://git.indyfac.ch/amin/fuzic"
|
||||||
|
WINDOW_TITLE="🔎🎶 $APP_NAME | a simple music finder and player"
|
||||||
|
export APP_NAME APP_VERSION APP_WEBSITE WINDOW_TITLE
|
||||||
|
|
||||||
|
export INFO_LOADED=1
|
||||||
|
fi
|
||||||
|
@@ -158,8 +158,7 @@ list_artists_from_json() {
|
|||||||
-v format_disambiguation="$AV_DISAMBIGUATION" \
|
-v format_disambiguation="$AV_DISAMBIGUATION" \
|
||||||
-v format_local="$FORMAT_LOCAL" \
|
-v format_local="$FORMAT_LOCAL" \
|
||||||
"$AWK_ARTISTS" |
|
"$AWK_ARTISTS" |
|
||||||
column -t -s "$(printf '\t')" |
|
column -t -s "$(printf '\t')" -l 2
|
||||||
sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\)$|\t\1\t\2|'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Generate playlist view
|
# Generate playlist view
|
||||||
|
244
src/sh/local.sh
244
src/sh/local.sh
@@ -1,3 +1,24 @@
|
|||||||
|
if [ ! "${LOCAL_LOADED:-}" ]; then
|
||||||
|
LOCALDATADIR="$HOME/.cache/$APP_NAME/local"
|
||||||
|
LOCALDATA_ARTISTS="$LOCALDATADIR/artists"
|
||||||
|
LOCALDATA_RELEASEGROUPS="$LOCALDATADIR/releasegroups"
|
||||||
|
LOCALDATA_RELEASES="$LOCALDATADIR/releases"
|
||||||
|
LOCALDATA_ARTISTS_VIEW="$LOCALDATADIR/artists_view"
|
||||||
|
LOCALDATA_RELEASEGROUPS_VIEW="$LOCALDATADIR/releasegroups_view"
|
||||||
|
LOCALDATA_RELEASES_VIEW="$LOCALDATADIR/releases_view"
|
||||||
|
LOCALDATA_ARTISTS_LIST="$LOCALDATADIR/artists_list"
|
||||||
|
LOCALDATA_RELEASEGROUPS_LIST="$LOCALDATADIR/releasegroups_list"
|
||||||
|
LOCALDATA_RELEASES_LIST="$LOCALDATADIR/releases_list"
|
||||||
|
DECORATION_FILENAME=${DECORATION_FILENAME:-"mbid.json"}
|
||||||
|
|
||||||
|
export LOCALDATADIR LOCALDATA_ARTISTS LOCALDATA_RELEASEGROUPS \
|
||||||
|
LOCALDATA_RELEASES LOCALDATA_ARTISTS_VIEW LOCALDATA_RELEASEGROUPS_VIEW \
|
||||||
|
LOCALDATA_RELEASES_VIEW LOCALDATA_ARTISTS_LIST LOCALDATA_RELEASEGROUPS_LIST \
|
||||||
|
LOCALDATA_RELEASES_LIST DECORATION_FILENAME
|
||||||
|
|
||||||
|
export LOCAL_LOADED=1
|
||||||
|
fi
|
||||||
|
|
||||||
gettags() {
|
gettags() {
|
||||||
ffprobe -v error -show_entries format_tags -print_format json "$1" |
|
ffprobe -v error -show_entries format_tags -print_format json "$1" |
|
||||||
$JQ '.format.tags | {
|
$JQ '.format.tags | {
|
||||||
@@ -47,75 +68,81 @@ decorate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Load missing cache entries (batch mode)
|
# Load missing cache entries (batch mode)
|
||||||
|
#
|
||||||
# argument $1: type
|
# argument $1: type
|
||||||
# argument $2: File with one ID per line
|
#
|
||||||
|
# This method reads one MusicBrainz IDs of the specified type from stdin (one
|
||||||
|
# per line), and fetches the missing items.
|
||||||
__batch_load_missing() {
|
__batch_load_missing() {
|
||||||
tmpf=$(mktemp)
|
tmpf=$(mktemp)
|
||||||
while IFS= read -r mbid; do
|
cat |
|
||||||
if ! in_cache "$1" "$mbid"; then
|
cache_get_file_batch "$1" |
|
||||||
echo "$mbid" >>"$tmpf"
|
xargs \
|
||||||
fi
|
sh -c 'for f; do [ -e "$f" ] || echo "$f"; done' _ |
|
||||||
done <"$2"
|
cache_mbid_from_path_batch >"$tmpf"
|
||||||
if [ -s "$tmpf" ]; then
|
|
||||||
lines=$(wc -l "$tmpf" | cut -d ' ' -f 1)
|
lines=$(wc -l "$tmpf" | cut -d ' ' -f 1)
|
||||||
if [ "$lines" -gt 0 ]; then
|
if [ "$lines" -gt 0 ]; then
|
||||||
case "$1" in
|
case "$1" in
|
||||||
"$TYPE_ARTIST")
|
"$TYPE_ARTIST") tt="artists" ;;
|
||||||
tt="artists"
|
"$TYPE_RELEASEGROUP") tt="release groups" ;;
|
||||||
;;
|
"$TYPE_RELEASE") tt="releases" ;;
|
||||||
"$TYPE_RELEASEGROUP")
|
|
||||||
tt="release groups"
|
|
||||||
;;
|
|
||||||
"$TYPE_RELEASE")
|
|
||||||
tt="releases"
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
info "Fetching $lines missing $tt"
|
info "Fetching missing $tt"
|
||||||
cnt=0
|
cnt=0
|
||||||
while IFS= read -r mbid; do
|
while IFS= read -r mbid; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
"$TYPE_ARTIST")
|
"$TYPE_ARTIST")
|
||||||
name=$(mb_artist "$mbid" | $JQ ".name")
|
name=$(mb_artist "$mbid" | $JQ '.name')
|
||||||
;;
|
|
||||||
"$TYPE_RELEASEGROUP")
|
|
||||||
name=$(mb_releasegroup "$mbid" | $JQ ".title")
|
|
||||||
;;
|
|
||||||
"$TYPE_RELEASE")
|
|
||||||
name=$(mb_release "$mbid" | $JQ ".title")
|
|
||||||
;;
|
;;
|
||||||
|
"$TYPE_RELEASEGROUP") name=$(mb_releasegroup "$mbid" | $JQ '.title') ;;
|
||||||
|
"$TYPE_RELEASE") name=$(mb_release "$mbid" | $JQ '.title') ;;
|
||||||
esac
|
esac
|
||||||
cnt=$((cnt + 1))
|
cnt=$((cnt + 1))
|
||||||
printf "\033[2K\r%d/%d (%s: %s)" "$cnt" "$lines" "$mbid" "$name"
|
info "$(printf "%d/%d (%s: %s)" "$cnt" "$lines" "$mbid" "$name")"
|
||||||
sleep 1
|
sleep 1
|
||||||
done <"$tmpf"
|
done <"$tmpf"
|
||||||
printf "\n"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
rm -f "$tmpf"
|
rm -f "$tmpf"
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCALDATADIR="$HOME/.cache/$APP_NAME/local"
|
|
||||||
LOCALDATA_ARTISTS="$LOCALDATADIR/artists"
|
|
||||||
LOCALDATA_RELEASEGROUPS="$LOCALDATADIR/releasegroups"
|
|
||||||
LOCALDATA_RELEASES="$LOCALDATADIR/releases"
|
|
||||||
LOCALDATA_ARTISTS_VIEW="$LOCALDATADIR/artists_view"
|
|
||||||
LOCALDATA_RELEASEGROUPS_VIEW="$LOCALDATADIR/releasegroups_view"
|
|
||||||
LOCALDATA_RELEASES_VIEW="$LOCALDATADIR/releases_view"
|
|
||||||
DECORATION_FILENAME=${DECORATION_FILENAME:-"mbid.json"}
|
|
||||||
|
|
||||||
# Precompute views
|
# Precompute views
|
||||||
precompute_view() {
|
__precompute_lists() {
|
||||||
info "Precomputing artist view"
|
cache_get_file_batch "$TYPE_ARTIST" <"$LOCALDATA_ARTISTS" | xargs \
|
||||||
while IFS= read -r aid; do
|
$JQ '[
|
||||||
mb_artist "$aid" | $JQ '[
|
|
||||||
.id,
|
.id,
|
||||||
.type,
|
.type,
|
||||||
.name,
|
.name,
|
||||||
.disambiguation,
|
.disambiguation,
|
||||||
.["life-span"].begin,
|
.["life-span"].begin,
|
||||||
.["life-span"].end
|
.["life-span"].end
|
||||||
] | join("\t")'
|
] | join("\t")' >"$LOCALDATA_ARTISTS_LIST"
|
||||||
done <"$LOCALDATA_ARTISTS" |
|
cache_get_file_batch "$TYPE_RELEASEGROUP" <"$LOCALDATA_RELEASEGROUPS" | xargs \
|
||||||
|
$JQ '[
|
||||||
|
.id,
|
||||||
|
."primary-type",
|
||||||
|
(."secondary-types" // []|join(";")),
|
||||||
|
."first-release-date",
|
||||||
|
.title,
|
||||||
|
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
|
||||||
|
] | join("\t")' >"$LOCALDATA_RELEASEGROUPS_LIST"
|
||||||
|
# cache_get_file_batch "$TYPE_RELEASE" <"$LOCALDATA_RELEASES" | xargs \
|
||||||
|
# $JQ '[
|
||||||
|
# .id,
|
||||||
|
# .status,
|
||||||
|
# .date,
|
||||||
|
# ."cover-art-archive".count,
|
||||||
|
# (."label-info" | map(.label.name) | unique | join(", ")),
|
||||||
|
# (.media | map(."track-count") | add),
|
||||||
|
# (.media | map(.format) | unique | join(", ")),
|
||||||
|
# .country,
|
||||||
|
# .title,
|
||||||
|
# (."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
|
||||||
|
# ] | join("\t")' >"$LOCALDATA_RELEASES_LIST" &
|
||||||
|
}
|
||||||
|
|
||||||
|
# Precompute views
|
||||||
|
# TODO: The sed opperations take too long, improve!
|
||||||
|
precompute_views() {
|
||||||
awk \
|
awk \
|
||||||
-F "\t" \
|
-F "\t" \
|
||||||
-v file_local_artists="${LOCALDATA_ARTISTS:-}" \
|
-v file_local_artists="${LOCALDATA_ARTISTS:-}" \
|
||||||
@@ -123,21 +150,11 @@ precompute_view() {
|
|||||||
-v format_group="$AV_GROUP" \
|
-v format_group="$AV_GROUP" \
|
||||||
-v format_disambiguation="$AV_DISAMBIGUATION" \
|
-v format_disambiguation="$AV_DISAMBIGUATION" \
|
||||||
-v format_local="$FORMAT_LOCAL" \
|
-v format_local="$FORMAT_LOCAL" \
|
||||||
"$AWK_ARTISTS" |
|
"$AWK_ARTISTS" "$LOCALDATA_ARTISTS_LIST" |
|
||||||
sort |
|
sort |
|
||||||
column -t -s "$(printf '\t')" -E 0 |
|
column -t -s "$(printf '\t')" -l 2 >"$LOCALDATA_ARTISTS_VIEW"
|
||||||
sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\)$|\t\1\t\2|' >"$LOCALDATA_ARTISTS_VIEW"
|
#column -t -s "$(printf '\t')" |
|
||||||
info "Precomputing releasegroup view"
|
#sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\)$|\t\1\t\2|' >"$LOCALDATA_ARTISTS_VIEW"
|
||||||
while IFS= read -r rgid; do
|
|
||||||
mb_releasegroup "$rgid" | $JQ '[
|
|
||||||
.id,
|
|
||||||
."primary-type",
|
|
||||||
(."secondary-types" // []|join(";")),
|
|
||||||
."first-release-date",
|
|
||||||
.title,
|
|
||||||
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
|
|
||||||
] | join("\t")'
|
|
||||||
done <"$LOCALDATA_RELEASEGROUPS" |
|
|
||||||
awk \
|
awk \
|
||||||
-F "\t" \
|
-F "\t" \
|
||||||
-v file_local_releasegroups="${LOCALDATA_RELEASEGROUPS:-}" \
|
-v file_local_releasegroups="${LOCALDATA_RELEASEGROUPS:-}" \
|
||||||
@@ -164,75 +181,60 @@ precompute_view() {
|
|||||||
-v format_demo="$FORMAT_TYPE_SECONDARY_DEMO" \
|
-v format_demo="$FORMAT_TYPE_SECONDARY_DEMO" \
|
||||||
-v format_fieldrec="$FORMAT_TYPE_SECONDARY_FIELDREC" \
|
-v format_fieldrec="$FORMAT_TYPE_SECONDARY_FIELDREC" \
|
||||||
-v format_local="$FORMAT_LOCAL" \
|
-v format_local="$FORMAT_LOCAL" \
|
||||||
"$AWK_RELEASEGROUPS" |
|
"$AWK_RELEASEGROUPS" "$LOCALDATA_RELEASEGROUPS_LIST" | sort -n -r |
|
||||||
sort -n -r |
|
|
||||||
cut -d "$(printf '\t')" -f 2- |
|
cut -d "$(printf '\t')" -f 2- |
|
||||||
column -t -s "$(printf '\t')" -E 0 |
|
column -t -s "$(printf '\t')" -l 5 >"$LOCALDATA_RELEASEGROUPS_VIEW"
|
||||||
sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\)$|\t\1\t\2|' >"$LOCALDATA_RELEASEGROUPS_VIEW"
|
#column -t -s "$(printf '\t')" |
|
||||||
info "Precomputing release view"
|
#sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\)$|\t\1\t\2|' >"$LOCALDATA_RELEASEGROUPS_VIEW"
|
||||||
cut -d "$(printf '\t')" -f 1 "$LOCALDATA_RELEASES" |
|
|
||||||
while IFS= read -r rid; do
|
|
||||||
mb_release "$rid" | $JQ '[
|
|
||||||
.id,
|
|
||||||
.status,
|
|
||||||
.date,
|
|
||||||
."cover-art-archive".count,
|
|
||||||
(."label-info" | map(.label.name) | unique | join(", ")),
|
|
||||||
(.media | map(."track-count") | add),
|
|
||||||
(.media | map(.format) | unique | join(", ")),
|
|
||||||
.country,
|
|
||||||
.title,
|
|
||||||
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
|
|
||||||
] | join("\t")'
|
|
||||||
done |
|
|
||||||
awk \
|
|
||||||
-F "\t" \
|
|
||||||
-v file_local_releases="${LOCALDATA_RELEASES:-}" \
|
|
||||||
-v release_official="$FORMAT_STATUS_OFFICIAL" \
|
|
||||||
-v release_promotion="$FORMAT_STATUS_PROMO" \
|
|
||||||
-v release_bootleg="$FORMAT_STATUS_BOOTLEG" \
|
|
||||||
-v release_pseudo="$FORMAT_STATUS_PSEUDO" \
|
|
||||||
-v release_withdrawn="$FORMAT_STATUS_WITHDRAWN" \
|
|
||||||
-v release_expunged="$FORMAT_STATUS_EXPUNGED" \
|
|
||||||
-v release_cancelled="$FORMAT_STATUS_CANCELLED" \
|
|
||||||
-v release_format="$RV_FORMAT" \
|
|
||||||
-v release_format_title_artist="$RV_TITLE_ARTIST" \
|
|
||||||
-v release_format_title="$RV_TITLE" \
|
|
||||||
-v release_format_artist="$RV_ARTIST" \
|
|
||||||
-v format_local="$FORMAT_LOCAL" \
|
|
||||||
"$AWK_RELEASES" |
|
|
||||||
sort -n -r |
|
|
||||||
cut -d "$(printf '\t')" -f 2- |
|
|
||||||
column -t -s "$(printf '\t')" -E 0 |
|
|
||||||
sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\):\(.*$\)$|\t\1\t\2\t\3|' >"$LOCALDATA_RELEASES_VIEW"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Load local music
|
# Load local music
|
||||||
|
#
|
||||||
# argument $1: path to decorated music files
|
# argument $1: path to decorated music files
|
||||||
load_local() {
|
#
|
||||||
[ -d "$LOCALDATADIR" ] || mkdir -p "$LOCALDATADIR"
|
# This method parses all decorations and generates a line-by-line database of
|
||||||
tmpreleases=$(mktemp)
|
# locally available artists, releases, and release groups.
|
||||||
[ -f "$tmpreleases" ] || exit 1
|
reloaddb() {
|
||||||
info "Locating and parsing decoration files ($DECORATION_FILENAME)"
|
rm -rf "$LOCALDATADIR"
|
||||||
|
mkdir -p "$LOCALDATADIR"
|
||||||
find "$1" -type f -name "$DECORATION_FILENAME" -print0 |
|
find "$1" -type f -name "$DECORATION_FILENAME" -print0 |
|
||||||
xargs -0 -P 4 $JQ '.releaseid+"\t"+input_filename' |
|
xargs -0 $JQ '.releaseid+"\t"+input_filename' >"$LOCALDATA_RELEASES"
|
||||||
tee "$LOCALDATA_RELEASES" |
|
# Get necessary metadata and setup lists
|
||||||
cut -d "$(printf '\t')" -f 1 >"$tmpreleases"
|
tmpreleases=$(mktemp)
|
||||||
__batch_load_missing "$TYPE_RELEASE" "$tmpreleases"
|
cut -d "$(printf '\t')" -f 1 "$LOCALDATA_RELEASES" |
|
||||||
# Get release groups and album artists
|
tee "$tmpreleases" |
|
||||||
while IFS= read -r rid; do
|
__batch_load_missing "$TYPE_RELEASE"
|
||||||
mb=$(mb_release "$rid")
|
tmpreleasefiles=$(mktemp)
|
||||||
echo "$mb" | $JQ '."release-group".id' >>"$LOCALDATA_RELEASEGROUPS"
|
cache_get_file_batch "$TYPE_RELEASE" <"$tmpreleases" >"$tmpreleasefiles"
|
||||||
echo "$mb" | $JQ '."release-group"."artist-credit" | map(.artist.id) | join("\n")' >>"$LOCALDATA_ARTISTS"
|
xargs \
|
||||||
done <"$tmpreleases"
|
$JQ '."release-group".id' \
|
||||||
tf=$(mktemp)
|
<"$tmpreleasefiles" >"$LOCALDATA_RELEASEGROUPS"
|
||||||
sort "$LOCALDATA_RELEASEGROUPS" | uniq >"$tf" && mv "$tf" "$LOCALDATA_RELEASEGROUPS"
|
xargs \
|
||||||
sort "$LOCALDATA_ARTISTS" | uniq >"$tf" && mv "$tf" "$LOCALDATA_ARTISTS"
|
$JQ '."release-group"."artist-credit" | map(.artist.id) | join("\n")' \
|
||||||
# Populate cache with missing data
|
<"$tmpreleasefiles" >"$LOCALDATA_ARTISTS"
|
||||||
__batch_load_missing "$TYPE_RELEASEGROUP" "$LOCALDATA_RELEASEGROUPS"
|
rm -f "$tmpreleases" "$tmpreleasefiles"
|
||||||
__batch_load_missing "$TYPE_ARTIST" "$LOCALDATA_ARTISTS"
|
tf1=$(mktemp)
|
||||||
rm -f "$tmpreleases"
|
tf2=$(mktemp)
|
||||||
info "Resetting views"
|
sort "$LOCALDATA_RELEASEGROUPS" | uniq >"$tf1"
|
||||||
rm -f "$LOCALDATA_ARTISTS_VIEW" "$LOCALDATA_RELEASEGROUPS_VIEW" "$LOCALDATA_RELEASES_VIEW"
|
mv "$tf1" "$LOCALDATA_RELEASEGROUPS"
|
||||||
precompute_view
|
sort "$LOCALDATA_ARTISTS" | uniq >"$tf2"
|
||||||
|
mv "$tf2" "$LOCALDATA_ARTISTS"
|
||||||
|
__batch_load_missing "$TYPE_RELEASEGROUP" <"$LOCALDATA_RELEASEGROUPS"
|
||||||
|
__batch_load_missing "$TYPE_ARTIST" <"$LOCALDATA_ARTISTS"
|
||||||
|
__precompute_lists
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if necessary cache files are present or not
|
||||||
|
local_files_present() {
|
||||||
|
cache_get_file_batch "$TYPE_ARTIST" <"$LOCALDATA_ARTISTS" | xargs ls >/dev/null 2>&1 || return 1
|
||||||
|
cache_get_file_batch "$TYPE_RELEASEGROUP" <"$LOCALDATA_RELEASEGROUPS" | xargs ls >/dev/null 2>&1 || return 1
|
||||||
|
cut -d "$(printf '\t')" -f 1 "$LOCALDATA_RELEASES" | cache_get_file_batch "$TYPE_RELEASEGROUP" | xargs ls >/dev/null 2>&1 || return 1
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Load missing files
|
||||||
|
load_missing_files() {
|
||||||
|
__batch_load_missing "$TYPE_ARTIST" <"$LOCALDATA_ARTISTS"
|
||||||
|
__batch_load_missing "$TYPE_RELEASEGROUP" <"$LOCALDATA_RELEASEGROUPS"
|
||||||
|
cut -d "$(printf '\t')" -f 1 "$LOCALDATA_RELEASES" | __batch_load_missing "$TYPE_RELEASE"
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,15 @@
|
|||||||
# Logging methods
|
# Logging methods
|
||||||
ERR="\033[38;5;196m"
|
if [ ! "${LOG_LOADED:-}" ]; then
|
||||||
INFO="\033[38;5;75m"
|
ERR="\033[38;5;196m"
|
||||||
OFF="\033[m"
|
INFO="\033[38;5;75m"
|
||||||
LOGDIR="$HOME/.local/state/$APP_NAME"
|
OFF="\033[m"
|
||||||
[ -d "$LOGDIR" ] || mkdir -p "$LOGDIR"
|
LOGDIR="$HOME/.local/state/$APP_NAME"
|
||||||
LOGFILE="$LOGDIR/log"
|
[ -d "$LOGDIR" ] || mkdir -p "$LOGDIR"
|
||||||
|
LOGFILE="$LOGDIR/log"
|
||||||
|
export ERR INFO OFF LOGFILE
|
||||||
|
|
||||||
|
export LOG_LOADED=1
|
||||||
|
fi
|
||||||
|
|
||||||
err() {
|
err() {
|
||||||
echo "$(date) [$$]>${ERR}ERROR:${OFF} ${1:-}" | tee -a "$LOGFILE" | cut -d ">" -f 2- >/dev/stderr
|
echo "$(date) [$$]>${ERR}ERROR:${OFF} ${1:-}" | tee -a "$LOGFILE" | cut -d ">" -f 2- >/dev/stderr
|
||||||
|
@@ -4,14 +4,21 @@
|
|||||||
# a higher-level playback functionality is provided.
|
# a higher-level playback functionality is provided.
|
||||||
|
|
||||||
# Available playback commands
|
# Available playback commands
|
||||||
PLAYBACK_CMD_PLAY="play"
|
if [ ! "${PLAYBACK_LOADED:-}" ]; then
|
||||||
PLAYBACK_CMD_QUEUE="queue"
|
PLAYBACK_CMD_PLAY="play"
|
||||||
PLAYBACK_CMD_QUEUE_NEXT="queue-next"
|
PLAYBACK_CMD_QUEUE="queue"
|
||||||
PLAYBACK_CMD_TOGGLE_PLAYBACK="toggle"
|
PLAYBACK_CMD_QUEUE_NEXT="queue-next"
|
||||||
PLAYBACK_CMD_PLAY_NEXT="next"
|
PLAYBACK_CMD_TOGGLE_PLAYBACK="toggle"
|
||||||
PLAYBACK_CMD_PLAY_PREV="prev"
|
PLAYBACK_CMD_PLAY_NEXT="next"
|
||||||
PLAYBACK_CMD_SEEK_FORWARD="seekf"
|
PLAYBACK_CMD_PLAY_PREV="prev"
|
||||||
PLAYBACK_CMD_SEEK_BACKWARD="seekb"
|
PLAYBACK_CMD_SEEK_FORWARD="seekf"
|
||||||
|
PLAYBACK_CMD_SEEK_BACKWARD="seekb"
|
||||||
|
export PLAYBACK_CMD_PLAY PLAYBACK_CMD_QUEUE PLAYBACK_CMD_QUEUE_NEXT \
|
||||||
|
PLAYBACK_CMD_TOGGLE_PLAYBACK PLAYBACK_CMD_PLAY_NEXT \
|
||||||
|
PLAYBACK_CMD_PLAY_PREV PLAYBACK_CMD_SEEK_FORWARD PLAYBACK_CMD_SEEK_BACKWARD
|
||||||
|
|
||||||
|
export PLAYBACK_LOADED=1
|
||||||
|
fi
|
||||||
|
|
||||||
# Obtain playback command from key press
|
# Obtain playback command from key press
|
||||||
# @argument $1: key
|
# @argument $1: key
|
||||||
|
@@ -1,11 +1,18 @@
|
|||||||
PLAYLIST_CMD_REMOVE="rm"
|
if [ ! "${PLAYLIST_LOADED:-}" ]; then
|
||||||
PLAYLIST_CMD_UP="up"
|
PLAYLIST_CMD_REMOVE="rm"
|
||||||
PLAYLIST_CMD_DOWN="down"
|
PLAYLIST_CMD_UP="up"
|
||||||
PLAYLIST_CMD_CLEAR="clear"
|
PLAYLIST_CMD_DOWN="down"
|
||||||
PLAYLIST_CMD_CLEAR_ABOVE="clear-above"
|
PLAYLIST_CMD_CLEAR="clear"
|
||||||
PLAYLIST_CMD_CLEAR_BELOW="clear-below"
|
PLAYLIST_CMD_CLEAR_ABOVE="clear-above"
|
||||||
PLAYLIST_CMD_SHUFFLE="shuffle"
|
PLAYLIST_CMD_CLEAR_BELOW="clear-below"
|
||||||
PLAYLIST_CMD_UNSHUFFLE="unshuffle"
|
PLAYLIST_CMD_SHUFFLE="shuffle"
|
||||||
|
PLAYLIST_CMD_UNSHUFFLE="unshuffle"
|
||||||
|
export PLAYLIST_CMD_REMOVE PLAYLIST_CMD_UP PLAYLIST_CMD_DOWN \
|
||||||
|
PLAYLIST_CMD_CLEAR PLAYLIST_CMD_CLEAR_ABOVE PLAYLIST_CMD_CLEAR_BELOW \
|
||||||
|
PLAYLIST_CMD_SHUFFLE PLAYLIST_CMD_UNSHUFFLE
|
||||||
|
|
||||||
|
export PLAYLIST_LOADED=1
|
||||||
|
fi
|
||||||
|
|
||||||
# Run playback commands
|
# Run playback commands
|
||||||
#
|
#
|
||||||
|
Reference in New Issue
Block a user