diff --git a/README.md b/README.md index 3bafc41..ffe69bc 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # vindauga -Download and display album art or display embedded (or folder-based) album art using a bash script; a largely rewritten fork of kunst +Display album art or display embedded (or folder-based) album art using a bash script. Massively simplified. ![vindauga logo](https://raw.githubusercontent.com/uriel1998/vindauga/master/vindauga.png "logo") @@ -20,43 +20,29 @@ Download and display album art or display embedded (or folder-based) album art u ## 1. About -`vindauga` is a program (and probably daemon) that finds or extracts (if needed) -the album art for the currently playing song in `mpd`, and then displays it in -a little window or as part of a `conky` display. +`vindauga` is a program that finds the album art for the currently playing song +in `audacious` or `mpd`, and then displays it in a little window or as part of +a `conky` display. -It is a (largely rewritten) fork of [kunst](https://github.com/sdushantha/kunst) -by Siddharth Dushantha. There were some behaviors of `kunst` that I wanted to -fix and improve upon, so I created `vindauga`. There is also a great debt to -[this blog post](http://lmazy.verrech.net/2011/01/cover-art-with-conky-and-mpd/) -by "Raphael" for the `conky` bits. +`vindauga` now loops on a timer. +it looks at the currently playing track from `audacious` first (because that's always local) +and if that's not running, then `mpd`. It then looks in the music directory to find +either `folder.jpg` or `cover.jpg`, and puts that in a cache directory for reading +by conky or what have you. -`vindauga` does not loop on a timer. Instead it waits for `mpd` to send a "player" -event. When it receives a "player" event, it wakes up and takes action. This makes -`vindauga` really lightweight as a daemon. - -When `vindauga` wakes up, it looks at the currently playing track from `mpd`. It -then checks its own cache of album artwork (see below for details), then the -music folder, then embedded artwork, then the CoverArt Archive (if the music -has the MusicBrainz ID embedded), then Deezer. It can also use [sacad](https://github.com/desbma/sacad) as -an album art provider. - -If none of those exist, it checks if there is a configured local directory -with images in it designated as placeholder images. If that doesn't exist, it -checks for a designated placeholder image. - -If that doesn't exist, it will use the optional `simple_placeholder_images` to -download a nice picture from online and use that as a temporary album cover. If *that* doesn't exist, then it decodes a built in default album image to the cache directory. -At that point, `sxiv` or `conky` can display the image. - -The filestructure in the cache is meant to be fairly straightforward and -obvious so that the images may be used (if desired) with other programs. +At that point `conky` or any other program can display the image, which is located at +`${XDG_CACHE_HOME}/vindauga/nowplaying.album.png` (and if you already had [yadshow](https://ideatrash.net/2023/10/get-a-quick-popup-of-your-current-cover-art-from-the-music-player-daemon-mpd.html) installed to +pop up music covers, it will create a symlink between `${XDG_CACHE_HOME}/vindauga` and `${XDG_CACHE_HOME}/yadshow`.) `vindauga` means "window". +All the album-art *finding* and *synchronizing* functionality has been moved and is +found with `f_fixer_covers`, as outlined in [this blog post](https://ideatrash.net/2023/10/finding-fixing-and-synchronizing-all-your-mp3-music-album-art-mostly-automatically-bash-script.html). + ## 2. License @@ -64,201 +50,46 @@ This project is licensed under the MIT license. For the full license, see `LICEN ## 3. Prerequisites -### These may already be installed on your system. - - * `curl` command-line tool for getting data using HTTP protocol. `curl` can be found on major Linux distributions. - * `wget` command-line tool for getting data using HTTP protocol. `wget` can be found on major Linux distributions. - * `grep` command-line tool used for parsing downloaded XML data. `grep` can be found on major Linux distributions. - * `sed` command-line tool for parsing string data. `sed` can be found on major Linux distributions. - * `awk` command-line tool for parsing string data. `awk` can be found on major Linux distributions. - * `ffmpeg` command-line tool for parsing string data. `ffmpeg` can be found on major Linux distributions. * `imagemagick` command-line tool for parsing string data. `imagemagick` can be found on major Linux distributions. - -### You may have to install these - - * `base64` command-line tool for encoding/decoding data. `base64` can be found on major Linux distributions. * `mpc` command-line tool for controlling mpd. `mpc` can be found on major Linux distributions. - * `mpd`, the music player daemon. `mpd` can be found on major Linux distributions. - * `jq` command-line tool for parsing JSON data. `jq` can be found on major Linux distributions or on [GitHub](https://github.com/stedolan/jq) - -### You do not have to choose all or any of these. - - * [Optional] `sacad`, the smart automatic cover downloader. `sacad` is on [Github](https://github.com/desbma/sacad). - * [Optional] `ionice`, to lower the io priority of the script. `ionice` can be found on major Linux distributions. - * [Optional] `sxiv`, the Simple X Image Viewer, available in most major distributions or on [GitHub](https://github.com/muennich/sxiv) - * [Optional] `conky`, a light-weight system monitor for X available in most major distributions or on [GitHub](https://github.com/brndnmtthws/conky) - * [Optional] `simple_placeholder_images` to subsitute in generic images found online when cover art is not found. Available on [GitHub](https://github.com/uriel1998/simple_placeholder_images),[GitLab](https://gitlab.com/uriel1998/simple_placeholder_images), or my [personal repository](https://git.faithcollapsing.com/simple_placeholder_images) + * `audtool` command-line tool for audacity. ## 4. How to use - * As a daemon: Execute `vindauga.sh` from the terminal. It is safe to run it as `vindauga.sh &` and use the `-k` switch to kill a running vindauga process. - * If `ionice` is detected, it is automatically applied to the current script. - * To run it once (for example, from within a `conky` configuration), execute `vindauga.sh -c` . Note that this is almost certainly less efficient than running it as a daemon. - * To not call `sxiv`, execute `vindauga -y`. - * To invoke vindauga's control of its conky window, execute `vindauga -z` - though realistically you should probably `vindauga -y -z`. - * To kill an existing background `vindauga`, execute `vindauga -k`. This will kill both the instance of `sxiv` in use and the background script. - - For example, as I use the conky interface, I have two keybinds. One calls `vindauga -y -z`. That starts vindauga and the conky interface. The other calls `vindauga -k` and kills the process efficiently. You can even do this in a single script. For example, a single binding that calls `vindauga_toggle.sh` will start the conky process and daemon, and a second run of it will turn it off. - -### Multiple MPD Hosts - -`vindauga` can handle watching two different MPD instances. I have one for -[streaming and whole-house audio](https://ideatrash.net/2020/06/weekend-project-whole-house-and-streaming-audio-for-free-with-mpd.html), -and a second on my laptop. In the ini file, I configured my *laptop* -instance as *MPDHost1* and the remote instance as *MPDHost2*. If -MPDHost1 is running, that's what displays. If it is *not* running, then -MPDHost2 is shown (it's always on). If I start playing on MPDHost1 again, -`vindauga` will automatically switch back to showing MPDHost1. It rechecks -the *process* for the idle loop for both hosts every "interval" (set in the -ini file) seconds. - -If MPDHost2 is not set, it just checks MPDHost1 by default. - -### vindauga.ini - -### ** NOTE ** The ini format has changed since version 0.9 - -The file `vindauga.ini` goes in `$HOME\.config`. - -``` -# Music Dir -musicdir=/home/USER/music -# Cache Dir -cachedir=/home/USER/.cache/vindauga -# Placeholder Image -placeholder_img= -# Placeholder Directory -placeholder_dir=/home/USER/vault/albumcovers -# Display Size -display_size= -#SXIV X position -XCoord=500 -#SXIV Y position -YCoord=100 -#Conkyfile Location -ConkyFile=/home/USER/.conky/vindauga_conkyrc -#Last FM API Key -LastfmAPIKey= -#MPD Hosts -MPDHost1=password@localhost -MPDHost2=pass@remotehost -#WebCover Base -webcovers= -interval= -conkybin= +Run `vindauga.sh` from the command line (or crontab, or even conky itself) at an +interval. The current album art is output at `${XDG_CACHE_HOME}/vindauga/nowplaying.album.png` +and the current song information is in a text file at `${XDG_CACHE_HOME}/vindauga/songinfo`. -``` +There is an example `conkyrc` included. Throughout, replace `/home/USER` with your +home directory. -### ** NOTE ** The ini format has changed since version 0.9 +* `${execi 3 /path/to/vindauga.sh}` -- conky executes the program every 3 seconds, no need for cron. +* `${exec head /home/USER/.cache/vindauga/songinfo | sed 's/ - /\n/g'}` -- this parses it into three lines +* `${if_match "${audacious_status}" == "Playing"}${audacious_bar 7,253}${endif}${if_mpd_playing}${mpd_bar 7,253}${endif}` -- status bar depending on whether audacious is running or not. -## 5. Album Art Cache -The cache - by default in `$HOME/.cache/vindauga` - stores the discovered and -cached album art in the format: - -`[ArtistName]-[AlbumName].album.jpg` - -This is deliberately *very* similar to the way `Ario` and other programs store -the information. - -For example, a partial list of my cache is: - -``` -Aesthetic Perfection-Love Like Lies.album.jpg -Asking Alexandria-A Lesson Never Learned.album.jpg -Avatar-Hail the Apocalypse.album.jpg -Fear Factory-Demanufacture.album.jpg -Front Line Assembly-Echoes.album.jpg -In Flames-I, the Mask.album.jpg -Kidneythieves-Zerøspace.album.jpg -KMFDM-Naïve: Hell to Go.album.jpg -Ministry-ΚΕΦΑΛΗΞΘ.album.jpg -Nine Inch Nails-24.24.2.2527 [Deceased].album.jpg -Skinny Puppy-Mind: The Perpetual Intercourse.album.jpg -THE FEVER 333-STRENGTH IN NUMB333RS.album.jpg -Throbbing Gristle-The First Annual Report of Throbbing Gristle.album.jpg -外山雄三-Civilization V.album.jpg - -``` - -When there is a special character - `/()&` - it is completely omitted in -writing the cache filename. This is intentional behavior to minimize the -number of times that the program chokes. (Hopefully zero!) +### MPD Hosts + +It assumes your music directory is in `${HOME}/Music`, that your album art is +named either `cover.jpg` or `folder.jpg` and that `mpc` is already +set up correctly. -The album and artist image are obtained from Deezer or Last.fm (if you obtain a -last.fm [API key](https://www.last.fm/api) and put it in the config file) and -stored in the cache directory. If [sacad](https://github.com/desbma/sacad) is -in your `$PATH` it will attempt to get album art using that provider. +It will attempt to use the environment variable `MPD_HOST`, and +if it is not found, will examine `${HOME}/.bashrc` to see if it is set there (if a +non-login shell) and set it for the program. If you have a password set for MPD, +you *must* use `MPD_HOST=Password@host` for it to work. -If you use the `ffixer_covers.sh` file, it will softlink from the music directory. -This is obviously superior in terms of space saved. +It will put the current cover in `${XDG_CACHE_HOME}/vindauga/nowplaying.album.png` +after making the corners of the cover rounded. If you are also using [yadshow](https://ideatrash.net/2023/10/get-a-quick-popup-of-your-current-cover-art-from-the-music-player-daemon-mpd.html), +it will symlink it so the two directories point to the same location to avoid duplicated effort. ## 6. Using with Conky I have enclosed a basic configuration for `conky` (as seen in the video above) -that has the information and layout that I want. You can obviously incorporate -this into your own conky or edit it to your aesthetic delight. Editing `conky` +that has the information and layout that I want. Editing `conky` configurations is well past the scope of this document. -See the file `vindauga_conkyrc` for the example. It includes both the base image -seen in the screenshot below as well as an XCF file if you wish to design your -own. If you have a newer version of conky, with the lua-style formatted config, -use `vindauga_conkyrc_newformat` instead. - -The conkyfile will have the MPD host and password settings dynamically changed -(by `sed`) by `vindauga`! +See the file `vindauga_conkyrc` for the example. ![Output example](https://raw.githubusercontent.com/uriel1998/vindauga/master/updated_vindauga_conky.png "Example output") -## 7. Using with SXIV - -In `kunst`, the call to `sxiv` does not include the `-S 2` switch. On my Debian -system, without that switch, `sxiv` does not change the image once loaded. - -Unfortunately, if `sxiv` tries to reload the image at the same time that a new -one is being loaded, it aborts. There is a PID check built in to `vindauga` -that relaunches `sxiv` if it's closed. If it is relaunched, it loads back to -the default location (or location specified in the rc file). - -### SXIV and OpenBox - -I use this configuration with my OpenBox: - -``` - - yes - above - no - yes - yes - all - -``` - -Or if you don't want to move it around, and have it be below other windows: - -``` - - no - below - no - yes - yes - 1 - - 1075 - 380 - - all - -``` - -## 8. Todo - - * Write folder.jpg and cover.jpg to music directories, if desired. - * Embed found album art, if desired. - * Create script to retrieve artwork without or using `vindauga` - * Incorporate makefile for those who want it? - * Automatically softlink data for Ario / GMPC - * Automatically softlink albumart for cantata - * Plugin for file output diff --git a/defaultcover.jpg b/defaultcover.jpg new file mode 100644 index 0000000..12f009f Binary files /dev/null and b/defaultcover.jpg differ diff --git a/ffixer_covers.sh b/ffixer_covers.sh deleted file mode 100755 index c592d49..0000000 --- a/ffixer_covers.sh +++ /dev/null @@ -1,332 +0,0 @@ -#!/bin/bash - -TMPDIR=$(mktemp -d) -startdir="$PWD" -dirlist=$(mktemp) - -function cleanup { - # I use trash-cli here instead of rm - # https://github.com/andreafrancia/trash-cli - # Obviously, substitute rm -f for trash if you want to use it. - find "$TMPDIR/" -iname "OTHER*" -exec trash {} \; - find "$TMPDIR/" -iname "FRONT_COVER*" -exec trash {} \; - find "$TMPDIR/" -iname "cover*" -exec trash {} \; - find "$TMPDIR/" -iname "ICON*" -exec trash {} \; - find "$TMPDIR/" -iname "ILLUSTRATION*" -exec trash {} \; - -} - -#https://www.reddit.com/r/bash/comments/8nau9m/remove_leading_and_trailing_spaces_from_a_variable/ -trim() { - local s=$1 LC_CTYPE=C - s=${s#"${s%%[![:space:]]*}"} - s=${s%"${s##*[![:space:]]}"} - printf '%s' "$s" -} - - - if [ -f "${CONFIGFILE}" ];then - echo "[info] Reading configuration" - while read -r line; do - key=$(echo "$line" | awk -F '=' '{print $1}') - value=$(echo "$line" | cut -d'=' -f 2- ) - case $key in - musicdir) MUSICDIR="${value}";; - cachedir) CACHEDIR="${value}";; - placeholder_img) placeholder_img="${value}";; - placeholder_dir) placeholder_dir="${value}";; - display_size) display_size="${value}";; - XCoord) XCoord="${value}";; - YCoord) YCoord="${value}";; - ConkyFile) ConkyFile="${value}";; - LastfmAPIKey) LastfmAPIKey="${value}";; - MPDHost1) MPDHost1="${value}";; - MPDHost2) MPDHost2="${value}";; - webcovers) webcovers="${value}";; - interval) interval="${value}";; - conkybin) conkybin="${value}";; - *) ;; - esac - done < "${CONFIGFILE}" - echo "[info] Finished reading configuration." - fi - - if [ -z "$MusicDir" ] || [ ! d "$MusicDir" ]; then MusicDir="$HOME/music"; fi - if [ -z "$display_size" ];then display_size=256; fi - if [ -z "$XCoord" ];then XCoord=64; fi - if [ -z "$YCoord" ];then YCoord=64; fi - if [ -z "$interval" ];then interval=1; fi - if [ -z "$cachedir" ];then cachedir="$HOME/.cache/vindauga" ; fi - if [ ! -d "$cachedir" ];then mkdir -p "$cachedir"; fi - if [ -z "$conkybin" ];then conkybin=$(which conky); fi - if [ -z "$ConkyFile" ];then - ConkyFile="$HOME/.conky/vindauga_conkyrc" - if [ ! -f ${ConkyFile} ];then - ConkyFile="${SCRIPT_DIR}/vindauga_conkyrc" - fi - fi - -SAVEIFS=$IFS -IFS=$(echo -en "\n\b") -ENTRIES=$(find -name '*.mp3' -printf '%h\n' | sort -u | grep -c / ) -CURRENTENTRY=1 -#find -H . -type f \( -name "*.bz2" -or -name "*.gz" -or -name "*.iso" -or -name "*.tgz" -or -name "*.rar" -or -name "*.zip" \) -exec chmod 666 '{}' ';' -find -name '*.mp3' -printf '%h\n' | sort -u | realpath -p > "$dirlist" -while read line -do - cleanup - TITLE="" - ALBUMARTIST="" - NEWTITLE="" - SONGFILE="" - SONGDIR="" - BOB="" - LOOPEND="False" - #SONGFILE="$file" - #SongDir=$(dirname "${SONGFILE}") - dir=$(echo "$line") - SongDir=$(echo "$dir") - fullpath=$(realpath "$dir") - SONGFILE=$(find "$fullpath" -name '*.mp3' | head -1) - echo "$CURRENTENTRY of $ENTRIES $dir" - CURRENTENTRY=$(($CURRENTENTRY+1)) - - #################################################################### - # Do cover files exist? If so, make sure both cover and folder exist. - #################################################################### - if [ -f "$fullpath/cover.png" ];then - convert "$fullpath/cover.png" "$fullpath/cover.jpg" - rm "$fullpath/cover.png" - fi - if [ -f "$fullpath/folder.png" ];then - convert "$fullpath/folder.png" "$fullpath/folder.jpg" - rm "$fullpath/folder.png" - fi - - if [ ! -f "$fullpath/cover.jpg" ] && [ -f "$fullpath/folder.jpg" ];then - cp "$fullpath/folder.jpg" "$fullpath/cover.jpg" - fi - if [ ! -f "$fullpath/folder.jpg" ] && [ -f "$fullpath/cover.jpg" ];then - cp "$fullpath/cover.jpg" "$fullpath/folder.jpg" - - fi - - #read - if [ ! -f "$fullpath/cover.jpg" ];then - echo "Nothing found in directory $fullpath" - ######################################################################## - # Getting data from song along with a - # sed one liner to remove any null bytes that might be in there - # Also switching to ffmpeg for most of the data; speeds it up a LOT - ######################################################################## awk '{for(i=2;i<=NF;++i)print $i}' - songdata=$(ffprobe "$SONGFILE" 2>&1) - # big long grep string to avoid all the possible frakups I found, lol - ARTIST=$(echo "$songdata" | grep "artist" | grep -v "mp3," | head -1 | awk -F ': ' '{for(i=2;i<=NF;++i)print $i}') - ALBUM=$(echo "$songdata" | grep "album" | head -1 | awk -F ': ' '{for(i=2;i<=NF;++i)print $i}' | tr '\n' ' ') - ARTIST=$(trim "$ARTIST") - ALBUM=$(trim "$ALBUM") - - CoverExist=$(echo "$songdata" | grep -c "front") - if [ $CoverExist -gt 0 ];then - DATA=`eyeD3 "$SONGFILE" 2>/dev/null | sed 's/\x0//g' ` - COVER=$(echo "$DATA" | grep "FRONT_COVER" ) - fi - - #################################################################### - # Does the MP3 have a cover file? - #################################################################### - - #################################################################### - # Albumart file, nothing in MP3 - # This adds the found album art INTO the mp3 - #################################################################### - #if [[ ! -z "$FILTER" ]] && [[ -z "$COVER" ]];then - # echo "### Cover art retrieved from music directory!" - # echo "### Cover art being copied to MP3 ID3 tags!" - # if [ -f "$SongDir/cover.jpg" ]; then - # if [ ! -f "$SongDir/folder.jpg" ]; then - # convert "$SongDir/cover.jpg" "$SongDir/folder.jpg" - # fi - # else - # if [ -f "$SongDir/folder.jpg" ]; then - # convert "$SongDir/folder.jpg" "$SongDir/cover.jpg" - # fi - # fi - # echo "$fullpath/cover.jpg" - # eyeD3 --add-image="$SongDir/cover.jpg":FRONT_COVER "$SONGFILE" 2>/dev/null - #fi - - #################################################################### - # MP3 cover, no file - #################################################################### - - eyeD3 --write-images="$TMPDIR" "$SONGFILE" 1> /dev/null - if [ -f "$TMPDIR/FRONT_COVER.png" ]; then - echo "### Converting PNG into JPG" - convert "$TMPDIR/FRONT_COVER.png" "$TMPDIR/FRONT_COVER.jpeg" - fi - # Catching when it's sometimes stored as "Other" tag instead of FRONT_COVER - # but only when FRONT_COVER doesn't exist. - if [ ! -f "$TMPDIR/FRONT_COVER.jpeg" ]; then - if [ -f "$TMPDIR/OTHER.png" ]; then - echo "converting PNG into JPG" - convert "$TMPDIR/OTHER.png" "$TMPDIR/OTHER.jpeg" - fi - if [ -f "$TMPDIR/OTHER.jpg" ]; then - cp "$TMPDIR/OTHER.jpg" "$TMPDIR/OTHER.jpeg" - fi - if [ -f "$TMPDIR/OTHER.jpeg" ]; then - cp "$TMPDIR/OTHER.jpeg" "$TMPDIR/FRONT_COVER.jpeg" - fi - if [ -f "$TMPDIR/FRONT_COVER.jpg" ]; then - cp "$TMPDIR/FRONT_COVER.jpg" "$TMPDIR/FRONT_COVER.jpeg" - fi - fi - if [ -f "$TMPDIR/FRONT_COVER.jpeg" ]; then - echo "### Cover art retrieved from MP3 ID3 tags!" - echo "### Cover art being copied to music directory!" - echo "$fullpath/cover.jpg" - cp "$TMPDIR/FRONT_COVER.jpeg" "$fullpath/cover.jpg" - cp "$TMPDIR/FRONT_COVER.jpeg" "$fullpath/folder.jpg" - - fi - - #################################################################### - # No albumart file, nothing in MP3 - #################################################################### - - ########################################################################## - # Attempt to get coverart from CoverArt Archive or Deezer - ########################################################################## - MBID="" - IMG_URL="" - API_URL="" - - if [ ! -f "$fullpath/folder.jpg" ];then - MBID=$(ffmpeg -i "$SongFile" 2>&1 | grep "MusicBrainz Album Id:" | awk -F ': ' '{print $2}') - if [ "$MBID" = '' ] || [ "$MBID" = 'null' ];then - API_URL="http://coverartarchive.org/release/$MBID/front" - IMG_URL=$(curl "$API_URL" | awk -F ': ' '{print $2}') - fi - - if [ "$IMG_URL" = '' ] || [ "$IMG_URL" = 'null' ];then - echo "Not on CoverArt Archive or Deezer" - else - # I don't know why curl hates me here. - #curl -o "$tempcover" "$IMG_URL" - wget -q "$IMG_URL" -O "$TMPDIR/FRONT_COVER.jpeg" - if [ -f "$TMPDIR/FRONT_COVER.jpeg" ];then - convert "$TMPDIR/FRONT_COVER.jpeg" "$fullpath/cover.jpg" - convert "$TMPDIR/FRONT_COVER.jpeg" "$fullpath/folder.jpg" - fi - fi - fi - - if [ ! -f "$fullpath/cover.jpg" ];then - glyrc cover --timeout 15 --artist "$ARTIST" --album "$ALBUM" --write "$TMPDIR/cover.tmp" --from "musicbrainz;discogs;coverartarchive;rhapsody;lastfm" - convert "$TMPDIR/cover.tmp" "$TMPDIR/cover.jpg" - fi - - ########################################################################## - # Attempt to find cover art via sacad if it's in $PATH - # (no cache cover, no local art in directory - ########################################################################## - if [ ! -f "$fullpath/folder.jpg" ];then - sacad_bin=$(which sacad) - if [ -f "${sacad_bin}" ];then - "${sacad_bin}" -d "${Artist}" "${Album}" 512 "$TMPDIR/FRONT_COVER.jpeg" - if [ -f "$TMPDIR/FRONT_COVER.jpeg" ];then - convert "$TMPDIR/FRONT_COVER.jpeg" "$fullpath/cover.jpg" - convert "$TMPDIR/FRONT_COVER.jpeg" "$fullpath/folder.jpg" - fi - fi - fi - #tempted to be a hard stop here, because sometimes these covers are just wrong. - if [ -f "$TMPDIR/cover.jpg" ]; then - cp "$TMPDIR/cover.jpg" "$fullpath/cover.jpg" - cp "$TMPDIR/cover.jpg" "$fullpath/folder.jpg" - echo "Cover art found online; you may wish to check it before embedding it." - - else - echo "No cover art found online or elsewhere." - fi - fi - - ########################################################################## - # Copy to vindauga cache, if exists And get artist image - ########################################################################## - - if [ -d "$cachedir" ];then - if [ -f "$fullpath/cover.jpg" ];then - SONGFILE=$(find "$fullpath" -name '*.mp3' | head -1) - songdata=$(ffprobe "$SONGFILE" 2>&1) - ARTIST=$(echo "$songdata" | grep "artist" | grep -v "mp3," | head -1 | awk -F ': ' '{for(i=2;i<=NF;++i)print $i}') - ALBUM=$(echo "$songdata" | grep "album" | head -1 | awk -F ': ' '{for(i=2;i<=NF;++i)print $i}' | tr '\n' ' ') - ARTIST=$(trim "$ARTIST") - ALBUM=$(trim "$ALBUM") - EscapedArtist=$(echo "$ARTIST" | sed -e 's/[/()&]//g') - EscapedAlbum=$(echo "$ALBUM" | sed -e 's/[/()&]//g') - cachecover=$(printf "%s/%s-%s-album.jpg" "$cachedir" "$EscapedArtist" "$EscapedAlbum") - cacheartist=$(printf "%s/%s-artist.jpg" "$cachedir" "$EscapedArtist") - - #Adding in glyrc search for artist image... - if [ ! -f "$cacheartist" ];then - glyrc artistphoto --timeout 15 --artist "$ARTIST" --album "$ALBUM" --write "$TMPDIR/artist.tmp" --from "discogs;lastfm;bbcmusic;rhapsody;singerpictures" - if [ -f "$TMPDIR/artist.tmp" ];then - convert "$TMPDIR/artist.tmp" "$cacheartist" - rm "$TMPDIR/artist.jpg" - fi - fi - - - if [ ! -f "$cacheartist" ];then - echo "Trying deezer..." - API_URL="https://api.deezer.com/search/artist?q=$EscapedArtist" && API_URL=${API_URL//' '/'%20'} - IMG_URL=$(curl -s "$API_URL" | jq -r '.data[0] | .picture_big ') - #deezer outputs a wonky url if there's no image match, this checks for it. - # https://e-cdns-images.dzcdn.net/images/artist//500x500-000000-80-0-0.jpg - check=$(awk 'BEGIN{print gsub(ARGV[2],"",ARGV[1])}' "$IMG_URL" "//") - - if [ "$check" != "1" ]; then - IMG_URL="" - fi - - - if [ ! -z "$LastfmAPIKey" ] && [ -z "$IMG_URL" ];then # deezer first, then lastfm - echo "Trying lastfm..." - METHOD=artist.getinfo - API_URL="https://ws.audioscrobbler.com/2.0/?method=$METHOD&artist=$EscapedArtist&api_key=$LastfmAPIKey&format=json" && API_URL=${API_URL//' '/'%20'} - IMG_URL=$(curl -s "$API_URL" | jq -r ' .artist | .image ' | grep -B1 -w "extralarge" | grep -v "extralarge" | awk -F '"' '{print $4}') - fi - - if [ ! -z "$IMG_URL" ];then - tempartist=$(mktemp) - wget -q "$IMG_URL" -O "$tempartist" - bob=$(file "$tempartist" | head -1) #It really is an image - sizecheck=$(wc -c "$tempartist" | awk '{print $1}') - # This test is because I *HATE* last.fm's default artist image - if [[ "$bob" == *"image data"* ]];then - if [ "$sizecheck" != "4195" ];then - convert "$tempartist" "$cacheartist" - rm "$tempartist" - fi - fi - fi - fi - - - - if [ ! -f "$cachecover" ];then - ln -s "$fullpath/cover.jpg" "$cachecover" - fi - ARTIST="" - if [ -f "$TMPDIR/artist.tmp" ];then - rm "$TMPDIR/artist.tmp" - fi - if [ -f "$tempartist" ];then - rm "$tempartist" - fi - fi - fi -done < "$dirlist" -IFS=$SAVEIFS diff --git a/vindauga.ini b/vindauga.ini deleted file mode 100644 index f35408d..0000000 --- a/vindauga.ini +++ /dev/null @@ -1,25 +0,0 @@ -# Music Dir -musicdir=/home/USER/music -# Cache Dir -cachedir=/home/USER/.cache/vindauga -# Placeholder Image -placeholder_img= -# Placeholder Directory -placeholder_dir=/home/USER/vault/albumcovers -# Display Size -display_size= -#SXIV X position -XCoord=500 -#SXIV Y position -YCoord=100 -#Conkyfile Location -ConkyFile=/home/USER/.conky/vindauga_conkyrc -#Last FM API Key -LastfmAPIKey= -#MPD Hosts -MPDHost1=pass@localhost -MPDHost2=pass@remotehost -#WebCover Base -webcovers= -interval= -conkybin= diff --git a/vindauga.rc b/vindauga.rc deleted file mode 100644 index c63536e..0000000 --- a/vindauga.rc +++ /dev/null @@ -1,19 +0,0 @@ -# Music Dir - -# Cache Dir - -# Placeholder Image - -# Placeholder Directory - -# Display Size - -#SXIV X position - -#SXIV Y position - -#Conkyfile Location - -#Last FM API Key - -#MPD Host string \ No newline at end of file diff --git a/vindauga.sh b/vindauga.sh index 23f7f6e..ed133f3 100755 --- a/vindauga.sh +++ b/vindauga.sh @@ -1,531 +1,144 @@ #!/bin/bash +############################################################################## # ┐ ┬o┌┐┐┬─┐┬─┐┬ ┐┌─┐┬─┐ # │┌┘│││││ ││─┤│ ││ ┬│─┤ # └┘ ││└┘│─┘┘ ││─┘│─┘┘ │ # -# by Steven Saus # -# A (rather rewritten) fork of kunst (originally by Siddharth Dushantha) - - -tempcover=$(mktemp) -tempartist=$(mktemp) -RunOnce="" -NoSXIV="false" -DynamicConky="false" -cachecover="" -SXIVPID="" -export XDG_CONFIG_HOME=$HOME/.config -export XDG_CACHE_HOME=$HOME/.cache -export XDG_DATA_HOME=$HOME/.local/share -USER="" -# Default config file, can be overriden in command line -CONFIGFILE="$HOME/.config/vindauga.ini" -# This is the global / active variable -MPDHost="" - -# Pull in plugins -export SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" -#for plugin in ${SCRIPT_DIR}/plugins/*;do -# source ${plugin} -#done - - -# Use ionice if it exists -HasIonice=$(which ionice) -if [ -f "$HasIonice" ];then - "$HasIonice" -c3 -p$$ -fi - - -############################################################################## -# Read Ini File +# (c) Steven Saus 2023 +# Licensed under the MIT license +# ############################################################################## -init () { - read_ini - set_defaults -} -read_ini () { - if [ -f "${CONFIGFILE}" ];then - echo "[info] Reading configuration" - while read -r line; do - key=$(echo "$line" | awk -F '=' '{print $1}') - value=$(echo "$line" | cut -d'=' -f 2- ) - case $key in - musicdir) MUSICDIR="${value}";; - cachedir) CACHEDIR="${value}";; - placeholder_img) placeholder_img="${value}";; - placeholder_dir) placeholder_dir="${value}";; - display_size) display_size="${value}";; - XCoord) XCoord="${value}";; - YCoord) YCoord="${value}";; - ConkyFile) ConkyFile="${value}";; - LastfmAPIKey) LastfmAPIKey="${value}";; - MPDHost1) MPDHost1="${value}";; - MPDHost2) MPDHost2="${value}";; - webcovers) webcovers="${value}";; - interval) interval="${value}";; - conkybin) conkybin="${value}";; - *) ;; - esac - done < "${CONFIGFILE}" - echo "[info] Finished reading configuration." +export SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" +LOUD=1 +SONGSTRING="" +SONGFILE="" +SONGDIR="" +COVERFILE="" +MPD_MUSIC_BASE="${HOME}/Music" +DEFAULT_COVER="${SCRIPT_DIR}/defaultcover.jpg" + + +function loud() { + if [ $LOUD -eq 1 ];then + echo "$@" fi } -set_defaults (){ - - if [ -z "$MusicDir" ] || [ ! d "$MusicDir" ]; then MusicDir="$HOME/music"; fi - if [ -z "$display_size" ];then display_size=256; fi - if [ -z "$XCoord" ];then XCoord=64; fi - if [ -z "$YCoord" ];then YCoord=64; fi - if [ -z "$interval" ];then interval=1; fi - if [ -z "$cachedir" ];then cachedir="$HOME/.cache/vindauga" ; fi - if [ ! -d "$cachedir" ];then mkdir -p "$cachedir"; fi - if [ -z "$conkybin" ];then conkybin=$(which conky); fi - if [ -z "$ConkyFile" ];then - ConkyFile="$HOME/.conky/vindauga_conkyrc" - if [ ! -f ${ConkyFile} ];then - ConkyFile="${SCRIPT_DIR}/vindauga_conkyrc" - fi - fi - - # If MPDHost isn't defined, check for env variable, and default to localhost - if [ -z "$MPDHost1" ];then - if [ ! -z "$MPD_HOST" ];then - MPDHost1="$MPD_HOST" - else - MPDHost1="localhost" - fi - fi - - if [ -z "$MPDHost2" ];then - MPDHost2="$MPDHost1" - fi - -echo "$MPDHost2" +if [ -z "${XDG_DATA_HOME}" ];then + export XDG_DATA_HOME="${HOME}/.local/share" + export XDG_CONFIG_HOME="${HOME}/.config" + export XDG_CACHE_HOME="${HOME}/.cache" +fi -# This is a base64 endcoded image which will be used if nothing is found -read -d '' DEFAULT_COVER << EOF -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 -EOF +if [ ! -d "${XDG_CACHE_HOME}" ];then + echo "Your XDG_CACHE_HOME variable is not properly set and does not exist." + exit 99 +fi - if [ -d "$placeholder_dir" ];then - hasimgs=$(ls "$placeholder_dir" | egrep "jpeg|jpg|png|gif" -c ) - if [ $hasimgs -lt 1 ]; then - if [ ! -f "$placeholder_img" ];then - echo "$DEFAULT_COVER" | base64 --decode > "$cachedir/default_cover.png" - placeholder_img="$cachedir/default_cover.png" - placeholder_dir="" # the directory didn't have images - fi - else - placeholder_img="" - fi +VINDAUGA_CACHE="${XDG_CACHE_HOME}/vindauga" +if [ ! -d "${VINDAUGA_CACHE}" ];then + if [ -d "${XDG_CACHE_HOME}/yadshow" ];then + ln -s "${XDG_CACHE_HOME}/yadshow" "${XDG_CACHE_HOME}/vindauga" else - if [ ! -f "$placeholder_img" ];then - echo "$DEFAULT_COVER" | base64 --decode > "$cachedir/default_cover.png" - placeholder_img="$cachedir/default_cover.png" - fi + loud "Making cache directory" + mkdir -p "${VINDAUGA_CACHE}" fi +fi - # Logic here - if there's a placeholder directory with png or jpg in it, - # use that. If not, see if there's a specific placeholder image. If not, - # then output one. - -} - -display_help() { - ############################################################################## - # Show help on cli - ############################################################################## - echo "usage: vindauga.sh [-h][-c][-y]" - echo " " - echo "┐ ┬o┌┐┐┬─┐┬─┐┬ ┐┌─┐┬─┐" - echo "│┌┘│││││ ││─┤│ ││ ┬│─┤" - echo "└┘ ┆┆└┘┆─┘┘ ┆┆─┘┆─┘┘ ┆" - echo "Download and display album art or display embedded album art" - echo " " - echo "optional arguments:" - echo " -h show this help message and exit" - echo " -c run once and exit" - echo " -y do not use sxiv (e.g. for the art to be picked up by conky)" - echo " -k kill an existing background instance of vindauga" - echo " -i use a specific configuration file" - echo " -t write mpc output to tempfile for remote mpc and conky" -} - -playtester () { - local playtest=$(mpc --host "$1" --format "" | head -2 | tail -1 | awk -F ']' '{print $1}' | grep -e '^\[p' -c ) - printf "%s" "${playtest}" -} - -mpd_infogetter () { - # Using the global variable here - IFS=$'\t' mpd_array=( $(mpc --host "$MPDHost" --format "\t%artist%\t%album%\t%file%\t%albumartist%\t%title%\t") ); - Artist=$(echo "${mpd_array[0]}" | sed -e 's/^[ \t]*//') - EscapedArtist=$(echo "${mpd_array[0]}" | sed -e 's/[/()&]//g') - Album=$(echo "${mpd_array[1]}" | sed -e 's/^[ \t]*//' ) - EscapedAlbum=$(echo "${mpd_array[1]}" | sed -e 's/[/()&]//g') - SongFile=$(echo "$MusicDir/${mpd_array[2]}" | sed -e 's/^[ \t]*//') - AlbumDir=$(dirname "$SongFile") - AlbumArtist=$(echo "${mpd_array[3]}" | sed -e 's/^[ \t]*//' ) - EscapedAlbumArtist=$(echo "${mpd_array[3]}" | sed -e 's/[/()&]//g') - Title=$(echo "${mpd_array[4]}" | sed -e 's/^[ \t]*//' ) - StatusLine=$(echo "${mpd_array[5]}" | tail -2 | head -1 | awk '{print $1" "$3 $4}') -} +if [ ! -f "${VINDAUGA_CACHE}/vindauga_bg.png" ];then + cp "${SCRIPT_DIR}/vindauga_bg.png" "${VINDAUGA_CACHE}/vindauga_bg.png" +fi -############################################################################## -# Big updating artist function -############################################################################## -update_artist() { +function round_rectangles (){ - - ###################################################################### - # Artist image - ###################################################################### - if [[ ! -f "$cacheartist" ]] ;then - - - if [ -z "$IMG_URL" ];then - API_URL="https://api.deezer.com/search/artist?q=$EscapedArtist" && API_URL=${API_URL//' '/'%20'} - IMG_URL=$(curl -s "$API_URL" | jq -r '.data[0] | .picture_big ') - #deezer outputs a wonky url if there's no image match, this checks for it. - # https://e-cdns-images.dzcdn.net/images/artist//500x500-000000-80-0-0.jpg - check=$(awk 'BEGIN{print gsub(ARGV[2],"",ARGV[1])}' "$IMG_URL" "//") - if [ "$check" != "1" ]; then - IMG_URL="" - fi - fi - - if [ ! -z "$LastfmAPIKey" ] && [ -z "$IMG_URL" ];then # deezer first, then lastfm - METHOD=artist.getinfo - API_URL="https://ws.audioscrobbler.com/2.0/?method=$METHOD&artist=$EscapedArtist&api_key=$LastfmAPIKey&format=json" && API_URL=${API_URL//' '/'%20'} - IMG_URL=$(curl -s "$API_URL" | jq -r ' .artist | .image ' | grep -B1 -w "extralarge" | grep -v "extralarge" | awk -F '"' '{print $4}') - fi - - wget -q "$IMG_URL" -O "$tempartist" - bob=$(file "$tempartist" | head -1) #It really is an image - sizecheck=$(wc -c "$tempartist" | awk '{print $1}') - if [[ "$bob" == *"image data"* ]];then - if [ "$sizecheck" != "4195" ];then - convert "$tempartist" "$cacheartist" - rm "$tempartist" - fi - fi - rm "$tempartist" - fi - + #NEED TO CLEAN UP FILE HANDLING AND OUTPUT AND SHIT + convert "${1}" \ + -format 'roundrectangle 1,1 %[fx:w+4],%[fx:h+4] 15,15' \ + -write info:tmp.mvg \ + -alpha set -bordercolor none -border 3 \ + \( +clone -alpha transparent -background none \ + -fill white -stroke none -strokewidth 0 -draw @tmp.mvg \) \ + -compose DstIn -composite \ + \( +clone -alpha transparent -background none \ + -fill none -stroke black -strokewidth 3 -draw @tmp.mvg \ + -fill none -stroke white -strokewidth 1 -draw @tmp.mvg \) \ + -compose Over -composite "${2}" + rm tmp.mvg } -############################################################################## -# Big updating cover function -############################################################################## -update_cover() { - ########################################################################## - # Test for existing cache - ########################################################################## - - # Preferentially using album artist if available. - if [ ! -z ${EscapedAlbumArtist} ];then - cacheartist=$(printf "%s/%s-artist.jpg" "$cachedir" "$EscapedAlbumArtist") - cachecover=$(printf "%s/%s-%s-album.jpg" "$cachedir" "$EscapedAlbumArtist" "$EscapedAlbum") - else - cacheartist=$(printf "%s/%s-artist.jpg" "$cachedir" "$EscapedArtist") - cachecover=$(printf "%s/%s-%s-album.jpg" "$cachedir" "$EscapedArtist" "$EscapedAlbum") - fi +function get_coverart () { - update_artist - - if [[ ! -f "$cachecover" ]] ;then - - ########################################################################## - # Get local cover art first - ########################################################################## - CoverImage=$(echo "$AlbumDir/folder.jpg") - if [ ! -f "$CoverImage" ];then - CoverImage=$(echo "$AlbumDir/cover.jpg") - if [ ! -f "$CoverImage" ];then - CoverImage=$(echo "$AlbumDir/folder.png") - if [ ! -f "$CoverImage" ];then - CoverImage=$(echo "$AlbumDir/cover.png") - if [ ! -f "$CoverImage" ]; then - TempString=$(ls "$AlbumDir" | egrep "jpeg|jpg|png|gif" | head -n 1) - CoverImage=$(echo "$AlbumDir/$TempString") - fi - fi - fi - fi - ########################################################################## - # Attempt to extract cover art from MP3 if not in musicdir - # (no cache cover, no local art in directory - ########################################################################## - - if [ ! -f "$CoverImage" ];then - ffmpeg -i "$SongFile" $tempcover -y &> /dev/null - STATUS=$? - # Check if the file has a embbeded album art - if [ $STATUS -eq 0 ];then - CoverImage=$(echo "$tempcover") - fi - fi - - ########################################################################## - # Attempt to get coverart from CoverArt Archive or Deezer - ########################################################################## - MBID="" - IMG_URL="" - API_URL="" - - if [ ! -f "$CoverImage" ];then - MBID=$(ffmpeg -i "$SongFile" 2>&1 | grep "MusicBrainz Album Id:" | awk -F ': ' '{print $2}') - if [ "$MBID" = '' ] || [ "$MBID" = 'null' ];then - API_URL="http://api.deezer.com/search/autocomplete?q=${mpd_array[0]}-${mpd_array[1]}" && API_URL=${API_URL//' '/'%20'} - IMG_URL=$(curl -s "$API_URL" | jq -r '.playlists.data[0] | .picture_big') - else - API_URL="http://coverartarchive.org/release/$MBID/front" - IMG_URL=$(curl "$API_URL" | awk -F ': ' '{print $2}') - fi - - if [ "$IMG_URL" = '' ] || [ "$IMG_URL" = 'null' ];then - echo "Not on CoverArt Archive or Deezer" - else - # I don't know why curl hates me here. - #curl -o "$tempcover" "$IMG_URL" - wget -q "$IMG_URL" -O "$tempcover" - if [ -f "$tempcover" ];then - CoverImage=$(echo "$tempcover") - fi - fi + ### Test audacious, local mpd, remote mpd ### + aud_status=$(audtool playback-status) + if [ "${aud_status}" == "playing" ];then + SONGSTRING=$(audtool current-song) + SONGFILE=$(audtool current-song-filename) + else + echo "hi" + # checking if MPD_HOST is set or exists in .bashrc + # if neither is set, will just go with defaults (which will fail if + # password is set.) + if [ "$MPD_HOST" == "" ];then + export MPD_HOST=$(cat "${HOME}/.bashrc" | grep MPD_HOST | awk -F '=' '{print $2}') fi - - ########################################################################## - # Attempt to find cover art via sacad if it's in $PATH - # (no cache cover, no local art in directory - ########################################################################## - if [ ! -f "$CoverImage" ];then - local sacad_bin=$(which sacad) - if [ -f "${sacad_bin}" ];then - "${sacad_bin}" -d "${Artist}" "${Album}" 512 "${tempcover}" - CoverImage=$(echo "$tempcover") - fi + status=$(mpc | grep -c -e "\[") + if [ $status -lt 1 ];then + echo "Not playing or paused" + else + SONGFILE="${MPD_MUSIC_BASE}"/$(mpc current --format %file%) + SONGSTRING=$(mpc current --format "%artist% - %album% - %title%") fi - - ########################################################################## - # Copy our found file to the cache - ########################################################################## - if [[ ! -f "$cachecover" ]] ; then - if [ -f "$CoverImage" ];then - - # use convert instead of copy here so it doesn't matter if it - # downloaded/found a png or jpg or jpeg - convert "$CoverImage" "$cachecover" - convert "$CoverImage" -resize "$display_size" "$cachedir"/nowplaying.album.jpg - fi - fi - else - convert "$cachecover" -resize "$display_size" "$cachedir"/nowplaying.album.jpg fi - if [ ! -f "$cachedir"/nowplaying.album.jpg ];then - if [ ! -z "$placeholder_dir" ];then - TempString=$(ls "$placeholder_dir" | egrep "jpeg|jpg|png|gif" | shuf | head -n 1) - CoverImage=$(echo "$placeholder_dir/$TempString") - convert "$CoverImage" -resize "$display_size" "$cachedir"/nowplaying.album.jpg + if [ -f "${SONGFILE}" ];then + SONGDIR=$(dirname "$(readlink -f "${SONGFILE}")") + + if [ -f "$SONGDIR"/folder.jpg ];then + COVERFILE="$SONGDIR"/folder.jpg else - phi=$(which imgholder.sh) - if [ -f "$phi" ];then - bob=$($phi -p picsum -o "$tempcover" ) - if [ -f "$tempcover" ];then - convert "$tempcover" -resize "$display_size" "$cachedir"/nowplaying.album.jpg - else - convert "$tempcover" -resize "$display_size" "$cachedir"/nowplaying.album.jpg - fi + if [ -f "$SONGDIR"/cover.jpg ];then + COVERFILE="$SONGDIR"/cover.jpg fi fi fi -} - - -pre_exit() { - # Get the proccess ID of vindauga and kill it. - # We are dumping the output of kill to /dev/null - # because if the user quits sxiv before they - # exit vindauga, an error will be shown - # from kill and we dont want that - if [ -f /tmp/sxiv.pid ];then - kill -9 $(cat /tmp/sxiv.pid) &> /dev/null - rm /tmp/sxiv.pid - fi - if [ -f /tmp/vconky.pid ];then - kill -9 $(cat /tmp/vconky.pid) &> /dev/null - rm /tmp/vconky.pid + echo "${SONGSTRING}" + if [ "$COVERFILE" == "" ];then + COVERFILE=${DEFAULT_COVER} fi + echo "${SONGSTRING}" > "${VINDAUGA_CACHE}/songinfo" + TEMPFILE3=$(mktemp) + convert "${COVERFILE}" -resize "600x600" "${TEMPFILE3}" + round_rectangles "${TEMPFILE3}" "${VINDAUGA_CACHE}/nowplaying.album.png" + rm "${TEMPFILE3}" } -killing() { - -pre_exit -VPID=$(cat /tmp/vindauga.pid) -rm /tmp/vindauga.pid -kill -9 "$VPID" &> /dev/null - -exit -} - -main() { - - # Flag to run some commands only once in the loop - FIRST_RUN=true - - # If there is a second MPD config, check player 1 - # If there is not a second MPD config, use player 1 as player - # If player 1 is running, use that. - # If player 1 is not, see if player 2 is up. - - while true; do - if [ ! -z "${MPDHost2}" ];then - local tempstatus=$(playtester "${MPDHost1}") - if [ ${tempstatus} -gt 0 ];then - MPDHost="${MPDHost1}" - else - tempstatus=$(playtester "${MPDHost2}") - if [ ${tempstatus} -gt 0 ];then - MPDHost="${MPDHost2}" - fi - fi - else - MPDHost="${MPDHost1}" - fi - - PercentDone=$(echo "${StatusLine}" | cut -d '(' -f 2- | cut -d '%' -f 1) - mpd_infogetter - -############## THIS NEEDS TO BE A MODULE -# printf " %s\n" "${Artist}" > ${cachedir}/nowplaying.txt -# printf " %s\n" "${Album}" >> ${cachedir}/nowplaying.txt -# printf " %s\n" "${Title}" >> ${cachedir}/nowplaying.txt -# printf " %s\n" "${StatusLine}" >> ${cachedir}/nowplaying.txt -# printf "%s\n" "${PercentDone}" > ${cachedir}/percent.txt -###################################################################### - - update_cover - - if [ ! -f "$cachedir"/nowplaying.album.jpg ];then - convert "$placeholder_img" -resize "$display_size" "$cachedir"/nowplaying.album.jpg - fi - - if [ "$NoSXIV" = "false" ];then - # USE SXIV - # Resetting SXIVPID if it tries to scroll *just* as we change - # covers. You will want to set a fixed position in your rc.xml - if [ ! -z "$SXIVPID" ];then - if ! ps -p "$SXIVPID" > /dev/null - then - FIRST_RUN=true - fi - fi - - if [ $FIRST_RUN == true ]; then - FIRST_RUN=false - # Display the album art using sxiv - geometrystring=$(printf "%sx%s+%s+%s" "$display_size" "$display_size" "$XCoord" "$YCoord") - sxiv -g "$geometrystring" -b "$cachedir"/nowplaying.album.jpg -S 2 -N "vindauga" & - echo $! >/tmp/sxiv.pid - # Save the process ID so that we can kill - # sxiv when the user exits the script - SXIVPID=$(echo $!) - fi - else - if [ "$DynamicConky" = "true" ]; then - # USE CONKY - # Resetting Conky if need be - if [ ! -z "$VCONKYPID" ];then - if ! ps -p "$VCONKYPID" > /dev/null - then - FIRST_RUN=true - fi - fi - # Test to make sure settings are up to dates - if [ ${MPDHost} != ${MPD_HOST} ];then - FIRST_RUN=true - fi - if [ $FIRST_RUN == true ]; then - FIRST_RUN=false - # Needed to set to see if reset needed of conky - conkympdhost=$(echo "${MPDHost}" | awk -F '@' '{print $2}') - conkympdpass=$(echo "${MPDHost}" | awk -F '@' '{print $1}') - # Needed for conky to use the right host stuff for MPD - sed -i "s/mpd_host.*/mpd_host = \'${conkympdhost}',/" "${ConkyFile}" - sed -i "s/mpd_password.*/mpd_password = \'${conkympdpass}\',/" "${ConkyFile}" - export MPD_HOST=${MPDHost} - ${conkybin} -c "$ConkyFile" & - echo $! >/tmp/vconky.pid - VCONKYPID=$(echo $!) - fi - fi - fi - - if [ "$RunOnce" = "true" ];then - break - fi - # Waiting for an event from mpd; play/pause/next/previous - # this is lets vindauga use less CPU :) - CHANGES="" - mpc --host "$MPDHost1" idle & &> /dev/null - MPC_PID1="$!" - mpc --host "$MPDHost2" idle & &> /dev/null - MPC_PID2="$!" - while [ -z ${CHANGES} ]; do - sleep ${interval} - if ps -p $MPC_PID1 > /dev/null; then - if ps -p $MPC_PID2 > /dev/null; then - continue - else - CHANGES="TRUE" - fi - else - CHANGES="TRUE" - fi - done - kill -9 "$MPC_PID1" &> /dev/null - kill -9 "$MPC_PID2" &> /dev/null - done +display_help() { + ############################################################################## + # Show help on cli + ############################################################################## + echo "usage: vindauga.sh [-h][-c][-y]" + echo " " + echo "┐ ┬o┌┐┐┬─┐┬─┐┬ ┐┌─┐┬─┐" + echo "│┌┘│││││ ││─┤│ ││ ┬│─┤" + echo "└┘ ┆┆└┘┆─┘┘ ┆┆─┘┆─┘┘ ┆" + echo "Download and display album art or display embedded album art" + echo " " + echo "optional arguments:" + echo " -h show this help message and exit" + echo " -c run once and exit" + echo " -y do not use sxiv (e.g. for the art to be picked up by conky)" + echo " -k kill an existing background instance of vindauga" + echo " -i use a specific configuration file" + echo " -t write mpc output to tempfile for remote mpc and conky" } -# Command Line Options -while [ $# -gt 0 ]; do -option="$1" - case $option - in - -i) shift - CONFIGFILE="$1" - shift;; - -c) RunOnce="true" - shift ;; - -h) display_help +if [ "$1" == "-h" ];then + display_help exit - shift ;; - -t) TEMPFILE="true" - shift ;; - -z) DynamicConky="true" - shift ;; - -y) NoSXIV="true" - shift ;; - -k) killing - shift ;; - esac -done - -echo "$$" > /tmp/vindauga.pid - -init -# Disable CTRL-Z because if we allowed this key press, -# then the script would exit but, sxiv would still be -# running -trap "" SIGTSTP +fi -trap pre_exit EXIT -main +get_coverart diff --git a/vindauga_conky_info.sh b/vindauga_conky_info.sh deleted file mode 100755 index bbca831..0000000 --- a/vindauga_conky_info.sh +++ /dev/null @@ -1,34 +0,0 @@ -#! /bin/bash - - function getInfo() { - #mpdinfo=$(mpc --host "$hoststring" ) - playingstring=$(echo "$mpdinfo" | head -1 | awk -F '[' '{print $1}' | fold -sw 58 | head -1 ) - percent=$(echo "$mpdinfo" | tail -2 | head -1 | awk '{print $4}') - printf "%s: %s" "$playingstring" "$percent" -} - -function isplaying() { - mpdinfo=$(mpc --host "$hoststring" | sed -e 's/[/()&]//g') - progress=$(echo "$mpdinfo" | tail -2 | head -1 | awk '{print $1" "$3 $4}') - check=$(echo "$progress" | grep -c '\[') -} - -function main() { - - hoststring="PASSWORD@localhost" - isplaying - if [ $check = 0 ];then - hoststring="PASSWORD@OTHER HOST" - isplaying - if [ $check = 0 ];then - echo "MPD is off" - else - getInfo - fi - else - getInfo - fi -} - -main - diff --git a/vindauga_conkyrc b/vindauga_conkyrc index 3342d47..a5bc136 100644 --- a/vindauga_conkyrc +++ b/vindauga_conkyrc @@ -1,66 +1,66 @@ -# — Window specifications — # -own_window yes -own_window_class vindauga_conky -own_window_transparent yes -own_window_type override -own_window_hints undecorated,sticky,skip_taskbar,skip_pager -double_buffer yes -no_buffers yes -update_interval 1 -total_run_times 0 -net_avg_samples 2 +conky.config = { +-- — Window specifications — # + own_window = true, + own_window_class = 'vindauga_conky', + own_window_transparent = true, + own_window_type = 'override', + own_window_hints = 'undecorated,sticky,skip_taskbar,skip_pager', + double_buffer = true, + no_buffers = true, + update_interval = 3, + total_run_times = 0, + net_avg_samples = 2, -override_utf8_locale yes + override_utf8_locale = true, -text_buffer_size 2048 -imlib_cache_size 0 + text_buffer_size = 2048, + imlib_cache_size = 0, -border_inner_margin 10 -border_outer_margin 0 + border_inner_margin = 10, + border_outer_margin = 0, -minimum_size 260 360 -maximum_size 260 360 + minimum_width = 260, minimum_height = 360, + maximum_size = '260 360', -alignment tr -gap_x 30 -gap_y 30 + alignment = 'top_right', + gap_x = 30, + gap_y = 30, -# — Graphics settings — # -draw_shades yes -draw_outline no -draw_borders no -draw_graph_borders no +-- — Graphics settings — # + draw_shades = true, + draw_outline = false, + draw_borders = false, + draw_graph_borders = false, -# — Text settings — # -use_xft yes -xftfont Fira Sans:size=9 -xftalpha 0.8 +-- — Text settings — # + use_xft = true, + font = 'Fira Sans:size=9', + xftalpha = 0.8, -default_color FFFFFF -default_gauge_size 47 25 -default_graph_size 47 25 -default_bar_size 253 5 + default_color = '#FFFFFF', + default_gauge_width = 47, default_gauge_height = 25, + default_graph_width = 47, default_graph_height = 25, + default_bar_width = 253, default_bar_height = 5, -uppercase no -use_spacer right + uppercase = false, + use_spacer = 'right', -color0 white -color1 orange -color2 green -mpd_password -mpd_host - -TEXT -${alignr}${image /home/steven/.conky/vindauga_bg.png -p -1,-1 -s 280x385}${if_mpd_playing}${alignr}${mpd_elapsed}/${mpd_length} MPD:${mpd_status} -${alignr}${mpd_artist 45} -${alignr}${mpd_album 45} -${alignr}${mpd_title 45} -${mpd_bar 7,253} -${image /home/steven/.cache/vindauga/nowplaying.album.jpg -p 12,110 -s 256x256} -${endif} + color0 = 'white', + color1 = 'orange', + color2 = 'green', + mpd_password = '4TmUAFS4TQsC', + mpd_host = 'stevesaus.xyz', +}; +conky.text = [[ +${execi 3 /path/to/vindauga.sh} +${alignr}${image /home/USER/.cache/vindauga/vindauga_bg.png -p -1,-1 -s 280x385} +${exec head /home/USER/.cache/vindauga/songinfo | sed 's/ - /\n/g'} +${if_match "${audacious_status}" == "Playing"}${audacious_bar 7,253}${endif}${if_mpd_playing}${mpd_bar 7,253}${endif} +${image /home/USER/.cache/vindauga/nowplaying.album.png -p 12,110 -s 256x256} +]]; diff --git a/vindauga_conkyrc_newformat b/vindauga_conkyrc_newformat deleted file mode 100644 index c6fb4d4..0000000 --- a/vindauga_conkyrc_newformat +++ /dev/null @@ -1,70 +0,0 @@ -conky.config = { --- — Window specifications — # - own_window = true, - own_window_class = 'vindauga_conky', - own_window_transparent = true, - own_window_type = 'override', - own_window_hints = 'undecorated,sticky,skip_taskbar,skip_pager', - double_buffer = true, - no_buffers = true, - update_interval = 3, - total_run_times = 0, - net_avg_samples = 2, - - override_utf8_locale = true, - - - text_buffer_size = 2048, - imlib_cache_size = 0, - - border_inner_margin = 10, - border_outer_margin = 0, - - minimum_width = 260, minimum_height = 360, - maximum_size = '260 360', - - - alignment = 'top_right', - gap_x = 30, - gap_y = 30, - - --- — Graphics settings — # - draw_shades = true, - draw_outline = false, - draw_borders = false, - draw_graph_borders = false, - --- — Text settings — # - use_xft = true, - font = 'Fira Sans:size=9', - xftalpha = 0.8, - - default_color = '#FFFFFF', - default_gauge_width = 47, default_gauge_height = 25, - default_graph_width = 47, default_graph_height = 25, - default_bar_width = 253, default_bar_height = 5, - - uppercase = false, - use_spacer = 'right', - - color0 = 'white', - color1 = 'orange', - color2 = 'green', - mpd_password = '4TmUAFS4TQsC', - mpd_host = 'localhost', - -}; - -conky.text = [[ -${alignr}${image /home/steven/.conky/vindauga_bg.png -p -1,-1 -s 280x385}${if_mpd_playing}${alignr}${mpd_elapsed}/${mpd_length} MPD:${mpd_status} -${alignr}${mpd_artist 45} -${alignr}${mpd_album 45} -${alignr}${mpd_title 45} -${mpd_bar 7,253} -${image /home/steven/.cache/vindauga/nowplaying.album.jpg -p 12,110 -s 256x256} -${endif} - - - -]]; diff --git a/vindauga_conkyrc_old b/vindauga_conkyrc_old deleted file mode 100644 index 1831576..0000000 --- a/vindauga_conkyrc_old +++ /dev/null @@ -1,81 +0,0 @@ -# — Window specifications — # -own_window yes -own_window_class vindauga_conky -own_window_transparent no -own_window_type override -own_window_hints undecorated,sticky,skip_taskbar,skip_pager -double_buffer yes -no_buffers yes -update_interval 4 -total_run_times 0 -net_avg_samples 2 - -override_utf8_locale yes - - -text_buffer_size 2048 -imlib_cache_size 0 - -border_inner_margin 10 -border_outer_margin 0 - -minimum_size 258 350 -maximum_size 258 350 - -alignment tr -gap_x 30 -gap_y 30 - - -# — Graphics settings — # -draw_shades no -draw_outline no -draw_borders no -draw_graph_borders no - -# — Text settings — # -use_xft yes -xftfont Fira Sans:size=9 -xftalpha 0.8 - -default_color FFFFFF -default_gauge_size 47 25 - -uppercase no -use_spacer right - -color0 white -color1 orange -color2 green - -#head logfile lines (next_check) Displays first N lines of supplied text file. The file is checked every 'next_check' update. If next_check is not supplied, Conky defaults to 2. Max of 30 lines can be displayed, or until the text buffer is filled. - -#if_existing file (string) if FILE exists, display everything between if_existing and the matching $endif. The optional second parameter checks for FILE containing the specified string and prints everything between $if_existing and the matching $endif. -#execbar command Same as exec, except if the first value return is a value between 0-100, it will use that number for a bar. The size for bars can be controlled via the default_bar_size config setting. -#execibar interval command Same as execbar, except with an interval - -#steven@bunyip:$ mpc --format "\n%artist%\n%album%\n%title%" -# -Aïsha Devi -DNA Feelings -Intentional Dreams -echo "[playing] #20/38 0:08/4:46 (2%)" | awk -F'[][]' '{print $2}' - -MPD_DOING echo "$mpcstring" | awk -F'[][]' '{print $2}' -MPD_PROGRESS echo "$mpcstring" | awk '{print $3}' -MPD_BAR echo "$mpcstring" | awk -F'[)(]' '{print $2}'| cut -d '%' -f1 -printf "%s MPD:%s\n%s\n%s\%s" "$MPD_PROGRESS" "$MPD_DOING" - -use exec and a helper script to get multiple mpd servers, duh - - -TEXT -${if_mpd_playing}${alignr}${mpd_elapsed}/${mpd_length}MPD:${mpd_status} -${alignr}${mpd_artist 45} -${alignr}${mpd_album 45} -${alignr}${mpd_title 45} - ${mpd_bar 7,253} - ${image /home/steven/.cache/vindauga/nowplaying.album.jpg -p 2,90 -s 256x256} -${endif} - - diff --git a/vindauga_toggle.sh b/vindauga_toggle.sh deleted file mode 100755 index 63d192e..0000000 --- a/vindauga_toggle.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -if [ -f /tmp/vindauga.pid ];then - - vindauga -k -else - vindauga -y -z & -fi