diff --git a/src/main.sh b/src/main.sh index a9f0b57..337acfd 100755 --- a/src/main.sh +++ b/src/main.sh @@ -23,6 +23,12 @@ set -eu # Load preview methods . "sh/preview.sh" +# Load cache functionality +. "sh/cache.sh" + +# Load MusicBrainz wrappers +. "sh/mb.sh" + if [ "${1:-}" = "--internal-preview-artist" ]; then __preview_artist "$2" exit 0 @@ -49,7 +55,7 @@ if [ "${1:-}" = "--internal-search" ]; then echo "$$" >"$PIDFILE" sleep 1 touch "$LOCKFILE" - mb_search_artists "$2" | + __api_mb_search_artists "$2" | $JQ -r '.artists[] | [.id, .type, .name, .disambiguation, .["life-span"].begin, .["life-span"].end] | join("\t")' | awk \ -F "\t" \ @@ -63,8 +69,8 @@ if [ "${1:-}" = "--internal-search" ]; then exit 0 fi -if [ "${1:-}" = "--internal-browse-artist" ]; then - mb_browse_release_groups "$2" | +if [ "${1:-}" = "--internal-list-releases" ]; then + __api_mb_browse_release_groups "$2" | $JQ -r '."release-groups"[] | [ .id, ."primary-type", @@ -131,7 +137,7 @@ while true; do case "${1:-}" in "--show-artist") sel=$( - $0 --internal-browse-artist "$2" | + $0 --internal-list-releases "$2" | $FZF \ --ansi \ --reverse \ diff --git a/src/sh/api.sh b/src/sh/api.sh index c8baa55..b67c911 100644 --- a/src/sh/api.sh +++ b/src/sh/api.sh @@ -1,5 +1,5 @@ # Argument: MB Artist ID -mb_browse_releases() { +__api_mb_browse_releases() { $CURL \ --get \ --data fmt=json \ @@ -10,7 +10,7 @@ mb_browse_releases() { } # Argument: MB Artist ID -mb_browse_release_groups() { +__api_mb_browse_release_groups() { $CURL \ --get \ --data fmt=json \ @@ -22,7 +22,7 @@ mb_browse_release_groups() { } # Argument: Search string -mb_search_artists() { +__api_mb_search_artists() { $CURL \ --get \ --data fmt=json \ @@ -32,7 +32,7 @@ mb_search_artists() { } # Argument: MB Artist ID -mb_get_artist() { +__api_mb_get_artist() { $CURL \ --get \ --data fmt=json \ @@ -42,7 +42,7 @@ mb_get_artist() { } # Argument: Discogs id -discogs_get_artist() { +__api_discogs_get_artist() { $CURL \ --get \ -A "$APP_NAME/$APP_VERSION ($APP_WEBSITE)" \ @@ -50,7 +50,7 @@ discogs_get_artist() { } # Argument: wikidata id -wikidata_get_links() { +__api_wikidata_get_sitelinks() { $CURL \ --get \ -A "$APP_NAME/$APP_VERSION ($APP_WEBSITE)" \ @@ -58,7 +58,7 @@ wikidata_get_links() { } # Argument: Wikipedia name (last part of URL) -wikipedia_en_get_summary() { +__api_wikipedia_en_get_summary() { $CURL \ --get \ -A "$APP_NAME/$APP_VERSION ($APP_WEBSITE)" \ diff --git a/src/sh/cache.sh b/src/sh/cache.sh new file mode 100644 index 0000000..872cd89 --- /dev/null +++ b/src/sh/cache.sh @@ -0,0 +1,72 @@ +CACHEDIR="$HOME/.cache/$APP_NAME" +[ -d "$CACHEDIR" ] || mkdir "$CACHEDIR" + +artist_mb_filename="musicbrainz.json" +artist_discogs_filename="discogs.json" +artist_wikidata_filename="wikidata.json" +artist_enwikipedia_filename="enwikipedia.json" + +# Super wrapper +# argument $1: MusicBrainz Artist ID +# argument $2: Filename of json file +__get_artist_json() { + f="$CACHEDIR/$1/$2" + [ -f "$f" ] || return + cat "$f" +} + +# Super wrapper +# argument $1: MusicBrainz Artist ID +# argument $2: Filename of json file +__put_artist_json() { + artistdir="$CACHEDIR/$1" + [ -d "$artistdir" ] || mkdir "$artistdir" + f="$artistdir/$2" + tmpf=$(mktemp) + cat >"$tmpf" + [ -s "$tmpf" ] && mv "$tmpf" "$f" || echo "{}" >"$f" +} + +# Returns the cached MusicBrainz data for the artist given by the MusicBrainz +# Artist ID in $1 +cache_get_artist_mb() { + __get_artist_json "$1" "$artist_mb_filename" +} + +# Returns the cached Discogs data for the artist given by the MusicBrainz +# Artist ID in $1 +cache_get_artist_discogs() { + __get_artist_json "$1" "$artist_discogs_filename" +} + +# Returns the cached Wikipedia (English) data for the artist given by the +# MusicBrainz Artist ID in $1 +cache_get_artist_enwikipedia() { + __get_artist_json "$1" "$artist_enwikipedia_filename" +} + +cache_get_artist_wikidata() { + __get_artist_json "$1" "$artist_wikidata_filename" +} + +# Read from stdin the MusicBrainz data for the artist given by the MusicBrainz +# Artist ID in $1, and cache it. +cache_put_artist_mb() { + cat | __put_artist_json "$1" "$artist_mb_filename" +} + +# Read from stdin the Discogs data for the artist given by the MusicBrainz +# Artist ID in $1, and cache it. +cache_put_artist_discogs() { + cat | __put_artist_json "$1" "$artist_discogs_filename" +} + +# Read from stdin the Wikipedia data (English) for the artist given by the +# MusicBrainz Artist ID in $1, and cache it. +cache_put_artist_enwikipedia() { + cat | __put_artist_json "$1" "$artist_enwikipedia_filename" +} + +cache_put_artist_wikidata() { + cat | __put_artist_json "$1" "$artist_wikidata_filename" +} diff --git a/src/sh/mb.sh b/src/sh/mb.sh new file mode 100644 index 0000000..858ee96 --- /dev/null +++ b/src/sh/mb.sh @@ -0,0 +1,56 @@ +# The only IDs uses here are MusicBrainz IDs + +__mb_artist_cache_or_fetch() { + mbartist="$(cache_get_artist_mb "$1" || true)" + if [ ! "$mbartist" ]; then + __api_mb_get_artist "$1" | cache_put_artist_mb "$1" + mbartist="$(cache_get_artist_mb "$1")" + fi + echo "$mbartist" +} + +# Get MusicBrainz json for artist +# @argument $1: MusicBrainz Artist ID +mb_artist() { + __mb_artist_cache_or_fetch "$1" +} + +# Get Wikidata json for artist +# @argument $1: MusicBrainz Artist ID +mb_artist_wikidata() { + wikidata=$(cache_get_artist_wikidata "$1" || true) + if [ ! "$wikidata" ] || [ "$wikidata" = "null" ]; then + wikidataid=$(mb_artist "$1" | + $JQ -r '.relations | + map(select(.type=="wikidata")) | + .[0].url.resource' | + awk -F "/" '{print $NF}') + [ ! "$wikidataid" ] || [ "$wikidataid" != "null" ] || return + __api_wikidata_get_sitelinks "$wikidataid" | cache_put_artist_wikidata "$1" + wikidata=$(cache_get_artist_wikidata "$1") + fi + echo "$wikidata" +} + +# Get Wikipedia (English) summary json for artist +# @argument $1: MusicBrainz Artist ID +mb_artist_enwikipedia() { + enwiki="$(cache_get_artist_enwikipedia "$1" || true)" + if [ ! "$enwiki" ] || [ "$enwiki" = "null" ]; then + # To fetch the wikipedia data, we need the wikipedia URL + # There are two possibly ways to get the wikipedia URL + # 1. From the website relations in MB (MB artists donw have wiki rels) + # 2. MB website relations -> Wikidata -> Wikipedia + # Lately, Wikipedia pages are not stored in the MB artist url relations. + # For obvious reasons it is recommended to link to wikidata only. So, we + # take the second route. + wikidata=$(mb_artist_wikidata "$1" || true) + wikiid=$(echo "$wikidata" | + $JQ -r '.enwiki.url' | + awk -F "/" '{print $NF}') + [ ! "$wikiid" ] || [ "$wikiid" != "null" ] || return + __api_wikipedia_en_get_summary "$wikiid" | cache_put_artist_enwikipedia "$1" + enwiki="$(cache_get_artist_enwikipedia "$1")" + fi + echo "$enwiki" +} diff --git a/src/sh/preview.sh b/src/sh/preview.sh index 8e16e6d..190fee3 100644 --- a/src/sh/preview.sh +++ b/src/sh/preview.sh @@ -1,35 +1,6 @@ -__description_from_wikidata() { - wiki=$(wikidata_get_links "$1" | $JQ -r '.enwiki' | awk -F "/" '{print $NF}') - [ ! "$wiki" ] || [ "$wiki" = "null" ] && return - desc=$(wikipedia_en_get_summary "$wiki" | $JQ -r '.extract') - [ ! "$wiki" ] || [ "$wiki" = "null" ] && return - echo "$desc" -} - -# For now, this prints the description of the artist. -# -# Source of information: -# 1. Wikipedia -# 2. Discogs +# Print preview of artist +# @input $1: MusicBrainz Artist ID __preview_artist() { - # Get artist information from MusicBrainz - artist_relations=$(mb_get_artist "$1" | $JQ -r ".relations") - wikidata=$(echo "$artist_relations" | - $JQ -r 'map(select(.type="wikidata")) | .[0].url.resource' | - awk -F "/" '{print $NF}') - if [ "$wikidata" ] && [ "$wikidata" != "null" ]; then - desc=$(__description_from_wikidata "$wikidata") - fi - # Alternative: Get information from Discogs - if [ ! "${desc:-}" ]; then - discogs=$(echo "$artist_relations" | - $JQ -r 'map(select(.type=="discogs")) | .[0].url.resource' | - awk -F "/" '{print $NF}') - [ ! "$discogs" ] || [ "$discogs" = "null" ] && return - desc=$(discogs_get_artist "$discogs" | - $JQ -r '.profile') - [ ! "$desc" ] || [ "$desc" = "null" ] && return - fi - + desc=$(mb_artist_enwikipedia "$1" | $JQ -r ".extract") echo "$desc" | fold -s -w "$FZF_PREVIEW_COLUMNS" | $CAT }