Compare commits
36 Commits
7afe0d8f34
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| ed12cef7e4 | |||
| 06485fbce7 | |||
| 214a1cda4c | |||
| d13436b963 | |||
| 4343521a46 | |||
| 6db95d3feb | |||
| a0f8e79665 | |||
| fde3b6edcb | |||
| c0463c0d5e | |||
| 3b66faed6f | |||
| 13f40e9720 | |||
| 2bf0506351 | |||
| 57ed2f6d0e | |||
| 6bfb7f0399 | |||
| 05661c0d98 | |||
| 08ea6cf56c | |||
| a4cb7d5c72 | |||
| 8c67085f05 | |||
| 11446031bf | |||
| 1c4611e833 | |||
| 076e3c0c5e | |||
| acb6ff7e1d | |||
| e1aaf14814 | |||
| dcc50fa9f2 | |||
| 2e919d6702 | |||
| c7ee2e997f | |||
| e8ed114bc2 | |||
| e6bb4bb425 | |||
| 7ac2f980b3 | |||
| 1d8a63bd9e | |||
| e3354c6c28 | |||
| 5b7e8ef4c3 | |||
| e7fe1aec98 | |||
| 99047aedba | |||
| a40e397a06 | |||
| dc45f26299 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1 @@
|
|||||||
demo
|
|
||||||
fuzic
|
fuzic
|
||||||
|
|||||||
7
LICENSE
Normal file
7
LICENSE
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Copyright © 2025 Ämin Baumeler
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
217
README.md
Normal file
217
README.md
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
🎧 Description and Use Case
|
||||||
|
---------------------------
|
||||||
|
This application allows for a keyboard-controlled maneuvering of your music library and the MusicBrainz database.
|
||||||
|
Your local library becomes "embedded" in MusicBrainz, and all metadata remains up-to-date without the need of tagging your files.
|
||||||
|
Control playback from your terminal while browsing the vast world of music releases.
|
||||||
|
|
||||||
|
🔍 Key Features
|
||||||
|
---------------
|
||||||
|
- [Fuzzily](https://github.com/junegunn/fzf) browse your music library
|
||||||
|
- Treat your local library as part of the [MusicBrainz universe](https://musicbrainz.org)
|
||||||
|
- Search the MusicBrainz database and discover music artists and releases
|
||||||
|
- Handle metadata without touching your audio files
|
||||||
|
- Fast and hackable application with [vim](https://www.vim.org)-like keybindings
|
||||||
|
- Save and load playlists
|
||||||
|
- Lyrics support
|
||||||
|
|
||||||
|
🎞️ Screenshot
|
||||||
|
-------------
|
||||||
|
### Search Artist on MusicBrainz
|
||||||
|
The MusicBrainz database is automatically searched after entering a query.
|
||||||
|
In the screenshot below, the emoji 🔆 indicates that some tracks of _Mc Solaar_ are available in the local music library.
|
||||||
|
They are played by hitting `<enter>`.
|
||||||
|

|
||||||
|
|
||||||
|
### Browse Local Music Library
|
||||||
|
Here, we fuzzily search an album of _Daft Punk._
|
||||||
|
The LP _Random Access Memories_ can be appended to the playlist by pressing `ctrl-alt-m`.
|
||||||
|
Alternatively, you may switch back to normal mode (`esc`) and then hit `;`.
|
||||||
|

|
||||||
|
|
||||||
|
### Playlist Control
|
||||||
|
You can easily control playback and edit the playlist in the playlist view.
|
||||||
|

|
||||||
|
|
||||||
|
🛠️ Requirements and Installation
|
||||||
|
--------------------------------
|
||||||
|
### Requirements
|
||||||
|
This is an almost[^1] POSIX-compliant shell script with inline `awk` elements (GNU flavored, we couldn't resist) that makes calls to:
|
||||||
|
- the command-line fuzzy finder [fzf](https://junegunn.github.io/fzf/),
|
||||||
|
- the command-line data transferrer [curl](https://curl.se),
|
||||||
|
- the command-line JSON processor [jq](https://jqlang.org),
|
||||||
|
- the command-line media player [mpv](https://mpv.io), and
|
||||||
|
- the command-line multipurpose relay [socat](http://www.dest-unreach.org/socat/).
|
||||||
|
|
||||||
|
[^1]: It is written in POSIX style, but we make use of zero terminated strings.
|
||||||
|
|
||||||
|
The following may improve your experience:
|
||||||
|
- the command-line multimedia prober [ffprobe](https://ffmpeg.org/ffprobe.html) _(optional, for automatic release detection)_,
|
||||||
|
- the command-line clipboard [xsel](http://www.kfish.org/software/xsel/) _(optional, for yanking urls)_,
|
||||||
|
- Noto fonts _(optional, for emojis in your terminal)_.
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
Run `./scripts/build.sh`, then copy `fuzic` to your preferred location, e.g., `~/.local/bin`, and make it executable.
|
||||||
|
|
||||||
|
🧩 Configuration
|
||||||
|
-----------------
|
||||||
|
Although **no configuration** is needed, this application may be customized using environment variables.
|
||||||
|
If the file `$XDG_CONFIG_HOME/fuzic/config` (defaults to `$HOME/.config/fuzic/config`) exists, then it will be sourced.
|
||||||
|
You may also specify an alternative location of the configuration file with the environment variable `CONFIGFILE`.
|
||||||
|
|
||||||
|
The **appearance** of the application is controlled using the environment variables defined in `src/sh/theme.sh`.
|
||||||
|
The directory `share/theme` contains example themes.
|
||||||
|
You may execute `CONFIGFILE=share/theme/plain.sh fuzic` to launch `fuzic` using an emojiless and colorless theme.
|
||||||
|
|
||||||
|
Custom **filters** can be defined using the environment variables from `src/sh/filter.sh`.
|
||||||
|
For instance, when you launch `F_2_LIST_ARTISTS="jazz" fuzic`, then the artist list can be queried for the word `jazz` by pressing `alt-2`.
|
||||||
|
|
||||||
|
Also the **key bindings** can be reconfigured to your liking.
|
||||||
|
For that, adjust the environment variables defined in `src/sh/keys.sh`.
|
||||||
|
|
||||||
|
Finally, you can **sort** the artists according to their [sort name](https://musicbrainz.org/doc/Style/Artist/Sort_Name) by specifying `SORT_ARTIST_DEFAULT=sort-artist-sortname`,
|
||||||
|
and the switch to alphabetical release-group sorting via `SORT_RG_DEFAULT=sort-rg-title`.
|
||||||
|
|
||||||
|
|
||||||
|
▶️ Usage
|
||||||
|
--------
|
||||||
|
For a quick start, run the application and hit `alt-?` to display the available key-bindings.
|
||||||
|
You may also open the application in one of the following predefined modes:
|
||||||
|
```
|
||||||
|
Usage: fuzic [OPTION]
|
||||||
|
|
||||||
|
GENERAL OPTIONS:
|
||||||
|
--help Show this help and exit
|
||||||
|
--artists Default options, list artists of local music
|
||||||
|
--albums List albums of local music
|
||||||
|
--search-artist Search artist on MusicBrainz
|
||||||
|
--search-album Search album on MusicBrainz
|
||||||
|
--artist <mbid> List release groups of given artist <mbid>
|
||||||
|
--releasegroup <mbid> List releases in given release group <mbid>
|
||||||
|
--release <mbid> Show release given by <mbid>
|
||||||
|
--playlists List stored playlists and exit
|
||||||
|
--load-playlist <playlist> Load specified playlist
|
||||||
|
|
||||||
|
MANAGE LOCAL MUSIC:
|
||||||
|
--decorate <path> Decorate directory containing a tagged release
|
||||||
|
--decorate-as <path> <mbid> Decorate directory as the relase <mbid>
|
||||||
|
--reload-database <path> Populate database with decorated local music from <path>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
🗄️ Local Music Library
|
||||||
|
----------------------
|
||||||
|
Instead of reading the tags from audio files, this application uses **decorations.**
|
||||||
|
The decoration of a folder is a JSON file that stores the relevant MusicBrainz IDs of the release the folder corresponds to.
|
||||||
|
This assumes that complete releases are stored within separate folders.
|
||||||
|
The application then fetches the relevant metadata, which is displayed to the user.
|
||||||
|
Folders can be decorated using `fuzic --decorate <path>` or `fuzic --decorate-as <path> <mbid>` commands.
|
||||||
|
The first version may be used on previously tagged files (using, e.g., [MusicBrainz Picard](https://picard.musicbrainz.org/)).
|
||||||
|
With this command, the folder gets decorated with the MusicBrainz IDs extracted from the files.
|
||||||
|
The latter version does not require the files to be tagged.
|
||||||
|
Instead, it decorates the files found in that folder as the release given by the [MusicBrainz Release ID](https://musicbrainz.org/doc/MusicBrainz_Identifier) `<mbid>`.
|
||||||
|
|
||||||
|
After decorating your folders, you may run `fuzic --reload-database <path>` to build your music library.
|
||||||
|
This command searches the path specified for decorated folders.
|
||||||
|
Once the local music library is built, it will display automatically when `fuzic` is launched.
|
||||||
|
|
||||||
|
### Workflow Example
|
||||||
|
```
|
||||||
|
$ fuzic --decorate ~/Music/Daft\ Punk/Random\ Access\ Memories
|
||||||
|
Info: Decorating /home/amin/Music/Daft Punk/Random Access Memories as release 5000a285-b67e-4cfc-b54b-2b98f1810d2e
|
||||||
|
$ fuzic --decorate-as ~/Music/Mc\ Solaar/Prose\ Combat 69e5cf67-7cea-4fe8-9129-9779f0a93d69
|
||||||
|
Info: Decorating /home/amin/Music/Mc Solaar/Prose Combat as the release Prose Combat by MC Solaar
|
||||||
|
Info: We discovered the following association:
|
||||||
|
Track 'Aubade' File './01 Aubade.m4a'
|
||||||
|
Track 'Obsolète' File './02 Obsolète.m4a'
|
||||||
|
Track 'Nouveau western' File './03 Nouveau western.m4a'
|
||||||
|
Track 'À la claire fontaine' File './04 À la claire fontaine.m4a'
|
||||||
|
Track 'Superstarr' File './05 Superstarr.m4a'
|
||||||
|
Track 'La Concubine de l’hémoglobine' File './06 La Concubine de l’hémoglobine.m4a'
|
||||||
|
Track 'Dévotion' File './07 Dévotion.m4a'
|
||||||
|
Track 'Temps mort' File './08 Temps mort.m4a'
|
||||||
|
Track 'L’NMIACCd’HTCK72KPDP' File './09 L’NMIACCd’HTCK72KPDP.m4a'
|
||||||
|
Track 'Séquelles' File './10 Séquelles.m4a'
|
||||||
|
Track 'Dieu ait son âme' File './11 Dieu ait son âme.m4a'
|
||||||
|
Track 'À dix de mes disciples' File './12 À dix de mes disciples.m4a'
|
||||||
|
Track 'La fin justifie les moyens' File './13 La fin justifie les moyens.m4a'
|
||||||
|
Track 'Relations humaines' File './14 Relations humaines.m4a'
|
||||||
|
Track 'Prose combat' File './15 Prose combat.m4a'
|
||||||
|
Info: Are the track correctly associated to the audio files? (yes/no) yes
|
||||||
|
$ fuzic --reload-database ~/Music
|
||||||
|
Info: Reloading information of local music directory /home/amin/Music
|
||||||
|
Info: Fetching missing releases
|
||||||
|
Info: 1/2 (5000a285-b67e-4cfc-b54b-2b98f1810d2e: Random Access Memories)
|
||||||
|
Info: 2/2 (69e5cf67-7cea-4fe8-9129-9779f0a93d69: Prose Combat)
|
||||||
|
Info: Fetching missing release groups
|
||||||
|
Info: 1/2 (aa997ea0-2936-40bd-884d-3af8a0e064dc: Random Access Memories)
|
||||||
|
Info: 2/2 (b199910b-0f90-3c88-b523-d6852b7612d3: Prose Combat)
|
||||||
|
Info: Fetching missing artists
|
||||||
|
Info: 1/2 (056e4f3e-d505-4dad-8ec1-d04f521cbb56: Daft Punk)
|
||||||
|
Info: 2/2 (bbbd2644-b4cb-4bb5-a442-315310f68a0b: MC Solaar)
|
||||||
|
Info: Done
|
||||||
|
```
|
||||||
|
|
||||||
|
⌨️ Basic Keys
|
||||||
|
-------------
|
||||||
|
As mentioned above, you may hit `alt-?` anytime to display the possible keys.
|
||||||
|
Note that `fuzic` allows for two modes: _normal mode_ and _insert mode._
|
||||||
|
Similar to `vim`, keys pressed in the _normal mode_ do not directly write to the input field, but are instead bound to other actions.
|
||||||
|
For instance, the keys `j` and `k` can be used to navigate the list down and up.
|
||||||
|
In the insert mode, triggered using `i`, `a`, or `/`, the keys directly modify the input field.
|
||||||
|
|
||||||
|
Some central keys are `<enter>` to start playback of the selected entry, `<space>` to pause playback, and `ctrl-p` to open the currently loaded playlist.
|
||||||
|
|
||||||
|
📝 Playlist Store
|
||||||
|
-----------------
|
||||||
|
Playlists can be saved, loaded and _shared._
|
||||||
|
To save a playlist, simply press `ctrl-s` when viewing your playlist.
|
||||||
|
To load a playlist, open the playlist store using `ctrl-o` while viewing your playlist.
|
||||||
|
Alternatively, you may start `fuzic` using the command-line parameters `fuzic --load-playlist <playlist>`.
|
||||||
|
Under the hood, a playlist is not more than a sequence of MusicBrainz IDs.
|
||||||
|
This means that `fuzic` users may share their playlists irrespective of the audio file locations and formats.
|
||||||
|
Possibly even more importantly, this means that you can preserve your playlist even if you reorganize your local music library:
|
||||||
|
You can safely share your playlists with your future self.
|
||||||
|
|
||||||
|
Playlists are stored under `XDG_DATA_HOME/fuzic/playlists`, which defaults to `~/.local/share/fuzic/playlists`.
|
||||||
|
You may also define the playlist directory using the `PLAYLIST_DIRECTORY` environment variable.
|
||||||
|
In `share/playlists` you find example playlists.
|
||||||
|
Thus, the command `PLAYLIST_DIRECTORY=share/playlists fuzic` launches this application with access to these example playlists.
|
||||||
|
|
||||||
|
📜 Lyrics
|
||||||
|
---------
|
||||||
|
By using the key `L` (normal mode), the lyrics of the selected track are displayed.
|
||||||
|
The lyrics are taken from (in that order)
|
||||||
|
1. the lyrics stored using `fuzic`, or
|
||||||
|
2. from the `.lrc` file with the same name as the audio file, or
|
||||||
|
3. from the audio-file tags (requires `ffprobe`), or
|
||||||
|
4. from a custom script.
|
||||||
|
|
||||||
|
To specify the custom script, you can set the `LYRICS_FETCH_CUSTOM` environment variable to point to an executable.
|
||||||
|
The executable reads a JSON string on the standard input, and is supposed to print the lyrics (see `share/lyrics/example.sh`).
|
||||||
|
|
||||||
|
You may also skip the first three sources and directly make a call to your custom script by using the key `Y` (normal mode).
|
||||||
|
|
||||||
|
The key `alt-L` opens the lyrics in a new window using the `EDITOR`.
|
||||||
|
This requires one of the following terminal emulators (`kitty`, `x-terminal-emulator`, `gnome-terminal`, `xterm`).
|
||||||
|
If you use another terminal emulator, you may specify the environment variable `EXTERNALEDIT` to hold the string such that
|
||||||
|
```sh
|
||||||
|
$ExTERNALEDIT "$file"
|
||||||
|
```
|
||||||
|
spawns a text editor with `$file` loaded inside a terminal emulator.
|
||||||
|
|
||||||
|
🧭 Planned Features
|
||||||
|
-------------------
|
||||||
|
The following features are planned:
|
||||||
|
- cover art and artist images
|
||||||
|
- genre support
|
||||||
|
- MusicBrainz collections and favorites
|
||||||
|
|
||||||
|
🌐 Information Sources
|
||||||
|
----------------------
|
||||||
|
Main metadata is fetched from the MusicBrainz database.
|
||||||
|
This application also access [wikidata](https://wikidata.org), [wikipedia](https://en.wikipedia.org), and [discogs](https://www.discogs.com).
|
||||||
|
In the future, more sources may be added.
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
This project is licensed under the [MIT License](./LICENSE).
|
||||||
BIN
screenshots/browse.png
Normal file
BIN
screenshots/browse.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 194 KiB |
BIN
screenshots/playlist.png
Normal file
BIN
screenshots/playlist.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 60 KiB |
BIN
screenshots/search.png
Normal file
BIN
screenshots/search.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 142 KiB |
@@ -10,7 +10,11 @@ tmpdir=$(mktemp -d)
|
|||||||
echo "🥚 ${GREEN}Internalize sourced files${OFF}"
|
echo "🥚 ${GREEN}Internalize sourced files${OFF}"
|
||||||
sed -E 's|\. "([^$].+)"$|cat src/\1|e' "$SRC" >"$tmpdir/1.sh"
|
sed -E 's|\. "([^$].+)"$|cat src/\1|e' "$SRC" >"$tmpdir/1.sh"
|
||||||
echo "🐔 ${GREEN}Internalize awk scripts${OFF}"
|
echo "🐔 ${GREEN}Internalize awk scripts${OFF}"
|
||||||
sed -E 's|@@include (.+)$|cat src/\1|e' "$tmpdir/1.sh" >"$NAME"
|
sed -E 's|@@include (.+)$|cat src/\1|e' "$tmpdir/1.sh" >"$tmpdir/2.sh"
|
||||||
|
echo "🥚 ${GREEN}Internalize awk libraries${OFF}"
|
||||||
|
sed -E 's|@include "(.+)"$|cat src/\1|e' "$tmpdir/2.sh" >"$tmpdir/3.sh"
|
||||||
|
echo "🐔 ${GREEN}Strip comments${OFF}"
|
||||||
|
grep -v "^ *# " "$tmpdir/3.sh" | grep -v "^ *#$" >"$NAME"
|
||||||
echo "🥚 ${GREEN}Make executable and cleanup${OFF}"
|
echo "🥚 ${GREEN}Make executable and cleanup${OFF}"
|
||||||
chmod +x "$NAME"
|
chmod +x "$NAME"
|
||||||
rm -rf "$tmpdir"
|
rm -rf "$tmpdir"
|
||||||
|
|||||||
25
share/lyrics/example.sh
Executable file
25
share/lyrics/example.sh
Executable file
@@ -0,0 +1,25 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Example script for `fuzic` to display the lyrics of a track. This script
|
||||||
|
# reads from stdin a JSON string and stores it in the variable `j`. The
|
||||||
|
# variable `tj` contains the JSON string of the track.
|
||||||
|
j="$(cat)"
|
||||||
|
tj="$(echo "$j" | jq -r '.trackid as $tid | .release.media[].tracks[] | select(.id == $tid)')"
|
||||||
|
# The following four variables are self-explanatory:
|
||||||
|
track_name="$(echo "$tj" | jq -r '.title')"
|
||||||
|
artist_name="$(echo "$tj" | jq -r '."artist-credit" | map([.name, .joinphrase] | join("")) | join("")')"
|
||||||
|
album_name="$(echo "$j" | jq -r '.release.title')"
|
||||||
|
duration="$(echo "$tj" | jq -r '.length / 1000 | round')"
|
||||||
|
# Now, you may call an API to fetch the lyrics for this track,
|
||||||
|
#
|
||||||
|
# curl \
|
||||||
|
# --get \
|
||||||
|
# --silent \
|
||||||
|
# --data-urlencode "track_name=$track_name" \
|
||||||
|
# --data-urlencode "artist_name=$artist_name" \
|
||||||
|
# --data-urlencode "album_name=$album_name" \
|
||||||
|
# --data-urlencode "duration=$duration" \
|
||||||
|
# "$URL"
|
||||||
|
#
|
||||||
|
# or simply print a template to write the lyrics yourself:
|
||||||
|
printf "Lyrics '%s' by '%s' (album: %s, duration: %s seconds)\n" "$track_name" "$artist_name" "$album_name" "$duration"
|
||||||
7
share/playlists/example
Normal file
7
share/playlists/example
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
e2276744-afe0-4ecd-9340-9e34f1526cc5 56e2c4d2-01b2-4bc6-a11f-ee6a50be9fa6
|
||||||
|
a75bb4c3-d1ce-4d35-aac5-2068f7c32805 8def9034-1cd7-4fe3-88c6-5c83fdc9537a
|
||||||
|
60a90232-228c-4ee2-af2f-07706fa13bd8 f9f5c049-b2f2-3ce7-93e3-956ce2c77d2c
|
||||||
|
13027e7b-340c-4478-8dda-df5fa4af3564 b2f18f14-7918-4856-bce3-b936fd628763
|
||||||
|
ca2e4dca-0ec3-411a-b2a0-60bb97107c2c d0c5cb23-ec7a-41ce-8a1c-3498aafdf527
|
||||||
|
486239ef-0be2-435b-963a-b9451f8c8c57 c6c3b393-fede-489e-bb77-23e32951ebc9
|
||||||
|
b3cf4db5-deb4-40b8-88bc-e016cca1104f c90ec13c-b406-3c15-83d3-8443304ccc6f
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
# Simple black-and-white theme
|
|
||||||
|
|
||||||
# Pointers
|
|
||||||
# ========
|
|
||||||
# Sign that indicates the existence of audio files
|
|
||||||
FORMAT_LOCAL="|>"
|
|
||||||
# Pointer to the track currently playing (playlist)
|
|
||||||
FORMAT_CURRENT="->"
|
|
||||||
|
|
||||||
# Input prompt
|
|
||||||
# =============
|
|
||||||
# Search prompt
|
|
||||||
SEARCH_PROMPT="search> "
|
|
||||||
|
|
||||||
# Headers
|
|
||||||
# =======
|
|
||||||
# Header that displays artist's name
|
|
||||||
HEADER_ARTIST="%s > "
|
|
||||||
# Header that displays the release-group name after artist's
|
|
||||||
HEADER_ARTIST_RELEASEGROUP="%s > %s > "
|
|
||||||
# Header that in addition to `HEADER_ARTIST_RELEASEGROUP` also shows some
|
|
||||||
# release information
|
|
||||||
HEADER_RELEASE="%s > %s > %s"
|
|
||||||
# The release information is formatted as follows (placeholders implicit):
|
|
||||||
HEADER_RELEASE_FORMAT="<<tracks>> tx <<media>> | <<label>> <<country>> <<year>>"
|
|
||||||
|
|
||||||
# Artist view
|
|
||||||
# ===========
|
|
||||||
# Artist string for persons
|
|
||||||
AV_PERSON="<<name>>"
|
|
||||||
# Artist string for groups
|
|
||||||
AV_GROUP="<<name>>"
|
|
||||||
# Artist disambiguation string
|
|
||||||
AV_DISAMBIGUATION=" (<<disambiguation>>)"
|
|
||||||
|
|
||||||
# Release-group view
|
|
||||||
# ==================
|
|
||||||
# Default release group string
|
|
||||||
RGV_RELEASE="<<title>>"
|
|
||||||
# Release group string if the artist name differs from the current artist
|
|
||||||
RGV_RELEASE_W_ARTIST="<<title>> by <<artist>>"
|
|
||||||
# Year of the release group
|
|
||||||
RGV_YEAR="[<<year>>]"
|
|
||||||
|
|
||||||
# Release-group types
|
|
||||||
# ===================
|
|
||||||
# Album
|
|
||||||
FORMAT_TYPE_ALBUM="[LP]"
|
|
||||||
# EP
|
|
||||||
FORMAT_TYPE_EP="[EP]"
|
|
||||||
# Single
|
|
||||||
FORMAT_TYPE_SINGLE="[single]"
|
|
||||||
# Broadcast
|
|
||||||
FORMAT_TYPE_BROADCAST="[broadcast]"
|
|
||||||
# Other
|
|
||||||
FORMAT_TYPE_OTHER="[other]"
|
|
||||||
# Flag to indicate that the given release group has associated secondary types.
|
|
||||||
FORMAT_TYPE_HAS_SECONDARY="%s xx"
|
|
||||||
# Style to represent secondary types (takes one %s placeholder)
|
|
||||||
FORMAT_TYPE_SECONDARY="(%s)"
|
|
||||||
# Secondary types
|
|
||||||
FORMAT_TYPE_SECONDARY_COMPILATION="compilation"
|
|
||||||
FORMAT_TYPE_SECONDARY_SOUNDTRACK="OST"
|
|
||||||
FORMAT_TYPE_SECONDARY_SPOKENWORD="spokenword"
|
|
||||||
FORMAT_TYPE_SECONDARY_INTERVIEW="interview"
|
|
||||||
FORMAT_TYPE_SECONDARY_AUDIOBOOK="book"
|
|
||||||
FORMAT_TYPE_SECONDARY_AUDIODRAMA="drama"
|
|
||||||
FORMAT_TYPE_SECONDARY_LIVE="live"
|
|
||||||
FORMAT_TYPE_SECONDARY_REMIX="remix"
|
|
||||||
FORMAT_TYPE_SECONDARY_DJMIX="DJ"
|
|
||||||
FORMAT_TYPE_SECONDARY_MIXTAPE="mixtape"
|
|
||||||
FORMAT_TYPE_SECONDARY_DEMO="demo"
|
|
||||||
FORMAT_TYPE_SECONDARY_FIELDREC="field rec"
|
|
||||||
|
|
||||||
# Artist Preview
|
|
||||||
# ==============
|
|
||||||
# Main preview format. Takes two %s placeholder. The first is for the artist
|
|
||||||
# biography. The second for the life span.
|
|
||||||
APV_FORMAT="\n\n%s\n\n%s"
|
|
||||||
# Specification of a date
|
|
||||||
APV_DATE="%s"
|
|
||||||
# Specification of a place
|
|
||||||
APV_PLACE="%s"
|
|
||||||
# Specification of a date and a place (in that order)
|
|
||||||
APV_DATEPLACE="%s in %s"
|
|
||||||
# String to represent when/where a person is born
|
|
||||||
APV_BORN="Born: %s"
|
|
||||||
# String to represent when/where a person died
|
|
||||||
APV_DIED="Died: %s"
|
|
||||||
|
|
||||||
# Release view
|
|
||||||
# ============
|
|
||||||
# Format of a string that represents a release.
|
|
||||||
RV_FORMAT="<<status>>\t<<tracks>> tracks\t<<media>>\t<<year>>\t<<country>>\t<<label>>"
|
|
||||||
# Additional string to display the release title and artist name
|
|
||||||
RV_TITLE_ARTIST="<<artist>> - <<title>>"
|
|
||||||
# Additional string to display the release title
|
|
||||||
RV_TITLE="<<title>>"
|
|
||||||
# Additional string to display the artist
|
|
||||||
RV_ARTIST="<<artist>>"
|
|
||||||
|
|
||||||
# Release Status
|
|
||||||
# ==============
|
|
||||||
FORMAT_STATUS_OFFICIAL="official"
|
|
||||||
FORMAT_STATUS_PROMO="promo"
|
|
||||||
FORMAT_STATUS_BOOTLEG="bootleg"
|
|
||||||
FORMAT_STATUS_PSEUDO="psuedo"
|
|
||||||
FORMAT_STATUS_WITHDRAWN="withdrawn"
|
|
||||||
FORMAT_STATUS_EXPUNGED="expunged"
|
|
||||||
FORMAT_STATUS_CANCELLED="cancelled"
|
|
||||||
|
|
||||||
# Recording view
|
|
||||||
# ==============
|
|
||||||
# Format of a track in a release
|
|
||||||
REC_FORMAT="<<med>>\t<<nr>>\t<<title>>\t<<artist>>\t<<duration>>"
|
|
||||||
# Format of a track in the playlist
|
|
||||||
REC_FORMAT_NO_NUMBER="<<title>>\t<<artist>>\t<<duration>>"
|
|
||||||
90
share/theme/lite.sh
Normal file
90
share/theme/lite.sh
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
# Colors (internal only)
|
||||||
|
ESC=$(printf '\033')
|
||||||
|
CARTIST="${ESC}[38;5;209m"
|
||||||
|
CYEAR="${ESC}[38;5;179m"
|
||||||
|
RED="${ESC}[31m"
|
||||||
|
GREEN="${ESC}[32m"
|
||||||
|
YELLOW="${ESC}[33m"
|
||||||
|
OFF="${ESC}[m"
|
||||||
|
|
||||||
|
# Pointers
|
||||||
|
# ========
|
||||||
|
# Sign that indicates the existence of audio files
|
||||||
|
FORMAT_LOCAL="${YELLOW}|>${OFF}"
|
||||||
|
|
||||||
|
# Input prompt
|
||||||
|
# =============
|
||||||
|
# General search prompt (for now only used when choosing one-of-many artist)
|
||||||
|
SEARCH_PROMPT="search> "
|
||||||
|
|
||||||
|
# General workings of format strings
|
||||||
|
#
|
||||||
|
# A format string (_FMT) contains placeholders, e.g., <<name>>. These
|
||||||
|
# placeholders are filled with the relevant information. A placeholder may
|
||||||
|
# occur zero times, once, or more than once. There are two types of
|
||||||
|
# placeholders: strings and items. A placeholder of type string comes with a
|
||||||
|
# variable containing a `printf` expression (_FMT_placeholder). This `printf`
|
||||||
|
# expression may be used to additionally modify the string passed. If the
|
||||||
|
# string passed is empty, then each corresponding placeholder is replaced
|
||||||
|
# with the empty string, i.e., the `printf` expression is bypassed. A
|
||||||
|
# placeholder of the alternative type (item) comes with a series of variables
|
||||||
|
# that encode constants to be used (_FMT_placeholder_XYZ).
|
||||||
|
#
|
||||||
|
# The items in the format string may be separated with "\t". This will induce
|
||||||
|
# a proper representation (using `column`). By default, all fields but the
|
||||||
|
# first are left aligned, and the first field is right aligned. This can be
|
||||||
|
# changed by setting the appropriate FMT_RIGHTALIGN variable. If that
|
||||||
|
# variable is empty, then the first field is right aligned. This means that
|
||||||
|
# at least one field must be right aligned.
|
||||||
|
#
|
||||||
|
# Artist view
|
||||||
|
# ===========
|
||||||
|
# <<flag>> item Indication for locally available audio files
|
||||||
|
# <<type>> item Indicator for single-person artist or group
|
||||||
|
# <<name>> string Artist name
|
||||||
|
# <<disambiguation>> string Disambiguation string
|
||||||
|
#
|
||||||
|
AV_FMT_TYPE_PERSON="${RED}P${OFF}"
|
||||||
|
AV_FMT_TYPE_GROUP="${RED}G${OFF}"
|
||||||
|
AV_FMT_NAME="${GREEN}%s${OFF}"
|
||||||
|
AV_FMT_DISAMBIGUATION="(%s)"
|
||||||
|
|
||||||
|
# Release-group view
|
||||||
|
# ==================
|
||||||
|
# <<flag>> item Indication for locally available audio files
|
||||||
|
# <<type>> item Indicates the type
|
||||||
|
# <<hassecondary>> item Indicates if there is some secondary type or none
|
||||||
|
# <<secondary>> string List of secondary types
|
||||||
|
# <<title>> string Title of album
|
||||||
|
# <<artist>> string Artist of album
|
||||||
|
# <<year>> string Year of initial release
|
||||||
|
# Note: The above <<secondary>> is of a joint item-string type. See code for
|
||||||
|
# details.
|
||||||
|
RGV_FMT="<<flag>>\t<<year>>\t<<title>>\t<<artist>>"
|
||||||
|
RGV_FMT_ARTIST="${CARTIST}%s${OFF}"
|
||||||
|
RGV_FMT_YEAR="${CYEAR}%s${OFF}"
|
||||||
|
|
||||||
|
# Release view
|
||||||
|
# ============
|
||||||
|
# <<flag>> item Indication for locally available audio files
|
||||||
|
# <<status>> item Release status
|
||||||
|
# <<tracks>> string Total number of track
|
||||||
|
# <<media>> string Media description
|
||||||
|
# <<year>> string Release year
|
||||||
|
# <<country>> string Release country
|
||||||
|
# <<label>> string Release label
|
||||||
|
# <<title>> string Optional titel string
|
||||||
|
# <<artist>> string Optional artist string
|
||||||
|
RV_FMT="<<flag>>\t<<year>>\t<<tracks>>\t<<media>>\t<<country>>\t<<label>>"
|
||||||
|
|
||||||
|
# Headers
|
||||||
|
# =======
|
||||||
|
# These header strings are based on the respective view and its fields
|
||||||
|
# defined above.
|
||||||
|
#
|
||||||
|
# Header that displays artist's name (based on artist view)
|
||||||
|
HEADER_ARTIST_FMT="\t<<name>>"
|
||||||
|
# Header that displays the release-group (based on release-group view)
|
||||||
|
HEADER_RG_FMT="\t<<artist>> / <<title>>"
|
||||||
|
# Header that displays the release (based on release view)
|
||||||
|
HEADER_R_FMT="\t<<artist>> / <<title>> / <<tracks>> tx <<media>>"
|
||||||
190
share/theme/plain.sh
Normal file
190
share/theme/plain.sh
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
# Pointers
|
||||||
|
# ========
|
||||||
|
# Sign that indicates the existence of audio files
|
||||||
|
FORMAT_LOCAL="|>"
|
||||||
|
|
||||||
|
# Input prompt
|
||||||
|
# =============
|
||||||
|
# General search prompt (for now only used when choosing one-of-many artist)
|
||||||
|
SEARCH_PROMPT="search> "
|
||||||
|
|
||||||
|
# General workings of format strings
|
||||||
|
#
|
||||||
|
# A format string (_FMT) contains placeholders, e.g., <<name>>. These
|
||||||
|
# placeholders are filled with the relevant information. A placeholder may
|
||||||
|
# occur zero times, once, or more than once. There are two types of
|
||||||
|
# placeholders: strings and items. A placeholder of type string comes with a
|
||||||
|
# variable containing a `printf` expression (_FMT_placeholder). This `printf`
|
||||||
|
# expression may be used to additionally modify the string passed. If the
|
||||||
|
# string passed is empty, then each corresponding placeholder is replaced
|
||||||
|
# with the empty string, i.e., the `printf` expression is bypassed. A
|
||||||
|
# placeholder of the alternative type (item) comes with a series of variables
|
||||||
|
# that encode constants to be used (_FMT_placeholder_XYZ).
|
||||||
|
#
|
||||||
|
# The items in the format string may be separated with "\t". This will induce
|
||||||
|
# a proper representation (using `column`). By default, all fields but the
|
||||||
|
# first are left aligned, and the first field is right aligned. This can be
|
||||||
|
# changed by setting the appropriate FMT_RIGHTALIGN variable. If that
|
||||||
|
# variable is empty, then the first field is right aligned. This means that
|
||||||
|
# at least one field must be right aligned.
|
||||||
|
#
|
||||||
|
# Artist view
|
||||||
|
# ===========
|
||||||
|
# <<flag>> item Indication for locally available audio files
|
||||||
|
# <<type>> item Indicator for single-person artist or group
|
||||||
|
# <<name>> string Artist name
|
||||||
|
# <<disambiguation>> string Disambiguation string
|
||||||
|
#
|
||||||
|
AV_FMT_TYPE_PERSON="P"
|
||||||
|
AV_FMT_TYPE_GROUP="G"
|
||||||
|
AV_FMT_NAME="%s"
|
||||||
|
AV_FMT_DISAMBIGUATION="(%s)"
|
||||||
|
|
||||||
|
# Release-group view
|
||||||
|
# ==================
|
||||||
|
# <<flag>> item Indication for locally available audio files
|
||||||
|
# <<type>> item Indicates the type
|
||||||
|
# <<hassecondary>> item Indicates if there is some secondary type or none
|
||||||
|
# <<secondary>> string List of secondary types
|
||||||
|
# <<title>> string Title of album
|
||||||
|
# <<artist>> string Artist of album
|
||||||
|
# <<year>> string Year of initial release
|
||||||
|
# Note: The above <<secondary>> is of a joint item-string type. See code for
|
||||||
|
# details.
|
||||||
|
RGV_FMT_TYPE_SINGLE="single"
|
||||||
|
RGV_FMT_TYPE_ALBUM="LP"
|
||||||
|
RGV_FMT_TYPE_EP="EP"
|
||||||
|
RGV_FMT_TYPE_BROADCAST="broadcast"
|
||||||
|
RGV_FMT_TYPE_OTHER="other"
|
||||||
|
RGV_FMT_HASSECONDARY_YES="xx"
|
||||||
|
RGV_FMT_SECONDARY="[xx: %s]"
|
||||||
|
RGV_FMT_SECONDARY_SOUNDTRACK="soundtrack"
|
||||||
|
RGV_FMT_SECONDARY_SPOKENWORD="spokenword"
|
||||||
|
RGV_FMT_SECONDARY_INTERVIEW="interview"
|
||||||
|
RGV_FMT_SECONDARY_AUDIOBOOK="audiobook"
|
||||||
|
RGV_FMT_SECONDARY_AUDIODRAMA="audio drama"
|
||||||
|
RGV_FMT_SECONDARY_LIVE="live"
|
||||||
|
RGV_FMT_SECONDARY_REMIX="remix"
|
||||||
|
RGV_FMT_SECONDARY_DJMIX="DJ-mix"
|
||||||
|
RGV_FMT_SECONDARY_MIXTAPE="mixtape"
|
||||||
|
RGV_FMT_SECONDARY_DEMO="demo"
|
||||||
|
RGV_FMT_SECONDARY_FIELDREC="field recording"
|
||||||
|
RGV_FMT_TITLE="%s"
|
||||||
|
RGV_FMT_ARTIST=" - %s"
|
||||||
|
RGV_FMT_YEAR="(%s)"
|
||||||
|
|
||||||
|
# Release view
|
||||||
|
# ============
|
||||||
|
# <<flag>> item Indication for locally available audio files
|
||||||
|
# <<status>> item Release status
|
||||||
|
# <<tracks>> string Total number of track
|
||||||
|
# <<media>> string Media description
|
||||||
|
# <<year>> string Release year
|
||||||
|
# <<country>> string Release country
|
||||||
|
# <<label>> string Release label
|
||||||
|
# <<title>> string Optional titel string
|
||||||
|
# <<artist>> string Optional artist string
|
||||||
|
RV_FMT="${RV_FMT:-"<<flag>>\t<<status>> >> \t<<tracks>>\t<<media>>\t<<year>>\t<<country>>\t<<label>>\t<<title>> <<artist>>"}"
|
||||||
|
RV_FMT_STATUS_OFFICIAL="official"
|
||||||
|
RV_FMT_STATUS_PROMO="promo"
|
||||||
|
RV_FMT_STATUS_BOOTLEG="bootleg"
|
||||||
|
RV_FMT_STATUS_PSEUDO="pseudo"
|
||||||
|
RV_FMT_STATUS_WITHDRAWN="withdrawn"
|
||||||
|
RV_FMT_STATUS_EXPUNGED="expunged"
|
||||||
|
RV_FMT_STATUS_CANCELLED="cancelled"
|
||||||
|
RV_FMT_TRACKS="%s tracks"
|
||||||
|
RV_FMT_MEDIA="%s"
|
||||||
|
RV_FMT_YEAR="%s"
|
||||||
|
RV_FMT_COUNTRY="%s"
|
||||||
|
RV_FMT_LABEL="%s"
|
||||||
|
RV_FMT_TITLE="as %s"
|
||||||
|
RV_FMT_ARTIST="by %s"
|
||||||
|
|
||||||
|
# Recording view
|
||||||
|
# ==============
|
||||||
|
# <<flag>> item Indication for locally available audio files
|
||||||
|
# <<media>> string Media identifier
|
||||||
|
# <<nr>> string Track number within media
|
||||||
|
# <<title>> string Track title
|
||||||
|
# <<artist>> string Track artist
|
||||||
|
# <<duration>> string Track duration
|
||||||
|
REC_FMT_MEDIA="%s"
|
||||||
|
REC_FMT_NR="%s"
|
||||||
|
REC_FMT_TITLE="%s"
|
||||||
|
REC_FMT_ARTIST="%s"
|
||||||
|
REC_FMT_DURATION="%s"
|
||||||
|
|
||||||
|
# Recording view (playlist)
|
||||||
|
# =========================
|
||||||
|
# <<playing>> item Mark for currently playing track
|
||||||
|
# <<title>> string Track title
|
||||||
|
# <<artist>> string Track artist
|
||||||
|
# <<duration>> string Track duration
|
||||||
|
PLYLST_FMT_PLAYING_YES="-->"
|
||||||
|
PLYLST_FMT_TITLE="%s"
|
||||||
|
PLYLST_FMT_ARTIST="%s"
|
||||||
|
PLYLST_FMT_DURATION="%s"
|
||||||
|
|
||||||
|
# Headers
|
||||||
|
# =======
|
||||||
|
# These header strings are based on the respective view and its fields
|
||||||
|
# defined above.
|
||||||
|
#
|
||||||
|
# Header that displays artist's name (based on artist view)
|
||||||
|
HEADER_ARTIST_FMT=":::\t<<name>> >"
|
||||||
|
|
||||||
|
# Header that displays the release-group (based on release-group view)
|
||||||
|
HEADER_RG_FMT=":::\t<<artist>> >> <<title>> >"
|
||||||
|
HEADER_RG_FMT_ARTIST="%s"
|
||||||
|
|
||||||
|
# Header that displays the release (based on release view)
|
||||||
|
#HEADER_RELEASE="${HEADER_RELEASE:-" ${CARTIST}%s$OFF 》${CTITLE}%s$OFF 〉%s"}"
|
||||||
|
#HEADER_RELEASE_FORMAT="${HEADER_RELEASE_FORMAT:-"${CRELINFO}<<tracks>> tx <<media>> $OFF|$CRELINFO <<label>> <<country>> <<year>>$OFF"}"
|
||||||
|
HEADER_R_FMT=":::\t<<artist>> >> <<title>> > <<tracks>> tx <<media>> | <<label>> <<country>> <<year>>"
|
||||||
|
HEADER_R_FMT_TRACKS="%s"
|
||||||
|
HEADER_R_FMT_MEDIA="%s"
|
||||||
|
HEADER_R_FMT_YEAR="%s"
|
||||||
|
HEADER_R_FMT_COUNTRY="%s"
|
||||||
|
HEADER_R_FMT_LABEL="%s"
|
||||||
|
HEADER_R_FMT_TITLE="%s"
|
||||||
|
HEADER_R_FMT_ARTIST="%s"
|
||||||
|
|
||||||
|
# Artist Preview
|
||||||
|
# ==============
|
||||||
|
# Lines that contain the pattern defined in PREVIEW_NO_WRAP (see
|
||||||
|
# `src/sh/preview.sh`) will not be wrapped.
|
||||||
|
#
|
||||||
|
# We distinguish between single-person and group artists.
|
||||||
|
#
|
||||||
|
# <<name>> | string | Artist name
|
||||||
|
# <<sortname>> | string | Artist sort name
|
||||||
|
# <<bio>> | string | Artist biography
|
||||||
|
# <<disambiguation>> | string | Artist disambiguation string
|
||||||
|
# <<alias>> | higher-order placeholder | Placeholder for aliases
|
||||||
|
# <<start> | higher-order placeholder | Placeholder for start string
|
||||||
|
# <<end>> | higher-order placeholder | Placeholder for end string
|
||||||
|
# <<url>> | higher-order placeholder | Placeholder for links
|
||||||
|
PREVIEW_ARTIST_PERSON_BIO="%s\n\n"
|
||||||
|
PREVIEW_ARTIST_PERSON_ALIAS="Also known as %s\n\n"
|
||||||
|
PREVIEW_ARTIST_PERSON_START="Born: %s\n"
|
||||||
|
PREVIEW_ARTIST_PERSON_END="Died: %s\n"
|
||||||
|
PREVIEW_ARTIST_PERSON_URL="\nLinks:\n%s\n"
|
||||||
|
PREVIEW_ARTIST_PERSON_URL_URLINDEX="%3d"
|
||||||
|
PREVIEW_ARTIST_PERSON_URL_URLNAME="%s"
|
||||||
|
PREVIEW_ARTIST_PERSON_URL_URLLINK="%s"
|
||||||
|
|
||||||
|
PREVIEW_ARTIST_GROUP_START="Founded: %s\n"
|
||||||
|
PREVIEW_ARTIST_GROUP_END="Dissolved: %s\n"
|
||||||
|
|
||||||
|
# Keybinding themes
|
||||||
|
# =================
|
||||||
|
# Format keybinding group
|
||||||
|
KBF_GROUP="%s"
|
||||||
|
# Format key
|
||||||
|
KBF_KEY="%s"
|
||||||
|
# Format description
|
||||||
|
KBF_DESC="%s"
|
||||||
|
|
||||||
|
# Playlist title
|
||||||
|
# ==============
|
||||||
|
TITLE_PLYLST=" Playlist "
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
# Simple theme without emojis
|
|
||||||
|
|
||||||
# Colors (internal only)
|
|
||||||
ESC=$(printf '\033')
|
|
||||||
RED="${ESC}[31m"
|
|
||||||
GREEN="${ESC}[32m"
|
|
||||||
YELLOW="${ESC}[33m"
|
|
||||||
BLUE="${ESC}[34m"
|
|
||||||
PURPLE="${ESC}[35m"
|
|
||||||
CYAN="${ESC}[36m"
|
|
||||||
WHITE="${ESC}[37m"
|
|
||||||
OFF="${ESC}[m"
|
|
||||||
|
|
||||||
# Pointers
|
|
||||||
# ========
|
|
||||||
# Sign that indicates the existence of audio files
|
|
||||||
FORMAT_LOCAL="${BLUE}|>$OFF"
|
|
||||||
# Pointer to the track currently playing (playlist)
|
|
||||||
FORMAT_CURRENT="${WHITE}-->$OFF"
|
|
||||||
|
|
||||||
# Input prompt
|
|
||||||
# =============
|
|
||||||
# Search prompt
|
|
||||||
SEARCH_PROMPT="search: "
|
|
||||||
|
|
||||||
# Headers
|
|
||||||
# =======
|
|
||||||
# Header that displays artist's name
|
|
||||||
HEADER_ARTIST="artist: %s"
|
|
||||||
# Header that displays the release-group name after artist's
|
|
||||||
HEADER_ARTIST_RELEASEGROUP="artist: %s / album: %s"
|
|
||||||
# Header that in addition to `HEADER_ARTIST_RELEASEGROUP` also shows some
|
|
||||||
# release information
|
|
||||||
HEADER_RELEASE="artist: %s / album: %s (%s)"
|
|
||||||
# The release information is formatted as follows (placeholders implicit):
|
|
||||||
HEADER_RELEASE_FORMAT="<<label>> <<year>>"
|
|
||||||
|
|
||||||
# Artist view
|
|
||||||
# ===========
|
|
||||||
# Artist string for persons
|
|
||||||
AV_PERSON="(P) ${CYAN}<<name>>$OFF"
|
|
||||||
# Artist string for groups
|
|
||||||
AV_GROUP="(G) ${CYAN}<<name>>$OFF"
|
|
||||||
# Artist disambiguation string
|
|
||||||
AV_DISAMBIGUATION="// <<disambiguation>>"
|
|
||||||
|
|
||||||
# Release-group view
|
|
||||||
# ==================
|
|
||||||
# Default release group string
|
|
||||||
RGV_RELEASE="${PURPLE}<<title>>$OFF"
|
|
||||||
# Release group string if the artist name differs from the current artist
|
|
||||||
RGV_RELEASE_W_ARTIST="${PURPLE}<<title>>$OFF by ${CYAN}<<artist>>$OFF"
|
|
||||||
# Year of the release group
|
|
||||||
RGV_YEAR="[<<year>>]"
|
|
||||||
|
|
||||||
# Release-group types
|
|
||||||
# ===================
|
|
||||||
# Album
|
|
||||||
FORMAT_TYPE_ALBUM="${YELLOW}LP$OFF"
|
|
||||||
# EP
|
|
||||||
FORMAT_TYPE_EP="${YELLOW}EP$OFF"
|
|
||||||
# Single
|
|
||||||
FORMAT_TYPE_SINGLE="${YELLOW}Single$OFF"
|
|
||||||
# Broadcast
|
|
||||||
FORMAT_TYPE_BROADCAST="${YELLOW}Broadcast$OFF"
|
|
||||||
# Other
|
|
||||||
FORMAT_TYPE_OTHER=""
|
|
||||||
# Flag to indicate that the given release group has associated secondary types.
|
|
||||||
FORMAT_TYPE_HAS_SECONDARY="%s ${RED}xx${OFF}"
|
|
||||||
# Style to represent secondary types (takes one %s placeholder)
|
|
||||||
FORMAT_TYPE_SECONDARY="${RED}(${OFF}%s${RED})${OFF}"
|
|
||||||
# Secondary types
|
|
||||||
FORMAT_TYPE_SECONDARY_COMPILATION="${YELLOW}compilation$OFF"
|
|
||||||
FORMAT_TYPE_SECONDARY_SOUNDTRACK="${YELLOW}soundtrack$OFF"
|
|
||||||
FORMAT_TYPE_SECONDARY_SPOKENWORD="${YELLOW}spokenword$OFF"
|
|
||||||
FORMAT_TYPE_SECONDARY_INTERVIEW="${YELLOW}interview$OFF"
|
|
||||||
FORMAT_TYPE_SECONDARY_AUDIOBOOK="${YELLOW}audiobook$OFF"
|
|
||||||
FORMAT_TYPE_SECONDARY_AUDIODRAMA="${YELLOW}audio drama$OFF"
|
|
||||||
FORMAT_TYPE_SECONDARY_LIVE="${YELLOW}live$OFF"
|
|
||||||
FORMAT_TYPE_SECONDARY_REMIX="${YELLOW}remix$OFF"
|
|
||||||
FORMAT_TYPE_SECONDARY_DJMIX="${YELLOW}DJ-mix$OFF"
|
|
||||||
FORMAT_TYPE_SECONDARY_MIXTAPE="${YELLOW}mixtape$OFF"
|
|
||||||
FORMAT_TYPE_SECONDARY_DEMO="${YELLOW}demo$OFF"
|
|
||||||
FORMAT_TYPE_SECONDARY_FIELDREC="${YELLOW}field recording$OFF"
|
|
||||||
|
|
||||||
# Artist Preview
|
|
||||||
# ==============
|
|
||||||
# Main preview format. Takes two %s placeholder. The first is for the artist
|
|
||||||
# biography. The second for the life span.
|
|
||||||
APV_FORMAT="\n\nBio:\n%s\n\n${WHITE}%s${OFF}"
|
|
||||||
# Specification of a date
|
|
||||||
APV_DATE="%s"
|
|
||||||
# Specification of a place
|
|
||||||
APV_PLACE="%s"
|
|
||||||
# Specification of a date and a place (in that order)
|
|
||||||
APV_DATEPLACE="%s in %s"
|
|
||||||
# String to represent when/where a person is born
|
|
||||||
APV_BORN="Born: %s"
|
|
||||||
# String to represent when/where a person died
|
|
||||||
APV_DIED="Died: %s"
|
|
||||||
|
|
||||||
# Release view
|
|
||||||
# ============
|
|
||||||
# Format of a string that represents a release.
|
|
||||||
RV_FORMAT="<<media>> (<<tracks>>, yr: <<year>>)\t<<label>>"
|
|
||||||
# Additional string to display the release title and artist name
|
|
||||||
RV_TITLE_ARTIST="${CYAN}<<artist>>$OFF - ${PURPLE}<<title>>$OFF"
|
|
||||||
# Additional string to display the release title
|
|
||||||
RV_TITLE="${PURPLE}<<title>>$OFF"
|
|
||||||
# Additional string to display the artist
|
|
||||||
RV_ARTIST="${CYAN}<<artist>>$OFF"
|
|
||||||
|
|
||||||
# Recording view
|
|
||||||
# ==============
|
|
||||||
# Format of a track in a release
|
|
||||||
REC_FORMAT="<<med>>\t${RED}<<nr>>$OFF\t${GREEN}<<title>>$OFF\t${CYAN}<<artist>>$OFF\t${WHITE}<<duration>>$OFF"
|
|
||||||
# Format of a track in the playlist
|
|
||||||
REC_FORMAT_NO_NUMBER="${GREEN}<<title>>$OFF\t${CYAN}<<artist>>$OFF\t${WHITE}<<duration>>$OFF"
|
|
||||||
@@ -1,47 +1,63 @@
|
|||||||
# List artists
|
# List artists
|
||||||
#
|
#
|
||||||
# parameter file_local_artists: This is an optional parameter with the path
|
# parameters:
|
||||||
# to a file with a MusicBrainz artist ID per
|
# flagfile: path to a file with a MusicBrainz artist ID per line (optional)
|
||||||
# line.
|
# sortby: sort selector (see `src/sh/awk.sh`)
|
||||||
# parameter format_person: This is the format string for single person
|
#
|
||||||
# artists, which includes the <<name>>
|
# theme parameters (see `src/sh/awk.sh` and `src/sh/theme.sh`)
|
||||||
# placeholder.
|
# format Format string
|
||||||
# parameter format_disambiguation: This is the format string for the
|
# flag_local Flag for locally available music
|
||||||
# disambiguation part of the artist, with a
|
# flag_nolocal Flag for locally unavailable music
|
||||||
# placeholder <<disambiguation>>.
|
# type_person Single-person artist indicator
|
||||||
# parameter format_group: This is as format_person, but for music
|
# type_group Artist group indicator
|
||||||
# groups.
|
# fmtname `printf` expression to transform artist names
|
||||||
# parameter format_local: String to indicate that there is some music
|
# fmtdisambiguation `printf` expression to transform disambiguation
|
||||||
# locally available of an artist
|
|
||||||
#
|
#
|
||||||
# This awk program takes as input a sequence of lines where the first item is
|
# This awk program takes as input a sequence of lines where the first item is
|
||||||
# the MusicBrainz artist ID, the second item is the type of the artist
|
# the MusicBrainz artist ID, the second item is the type of the artist
|
||||||
# ("Person" or "Group"), the third item is the name, and the forth item is a
|
# ("Person" or "Group"), the third item is the name, the forth item is the sort
|
||||||
# disambiguation string.
|
# string, and the fifth item is a disambiguation string.
|
||||||
#
|
#
|
||||||
# The output of this script is a sequence of tab-delimited lines where the
|
# The output of this script is a sequence of tab-delimited lines. The first
|
||||||
# first item is the format_local string, if some music of that artist is
|
# `AV_FMT_CNT` lines are those that will be displayed to the user. The following lines are
|
||||||
# locally accessible, and the empty string otherwise, the second item is the
|
# - Field intended for sorting
|
||||||
# formatted artist string (formatted according to format_person or
|
# - constant 0 (field intended for parent id)
|
||||||
# format_group), the third item is the constant string "0" indicating the
|
# - MusicBrainz artist ID
|
||||||
# parent MusicBrainz ID, and the last item is the MusicBrainz artist ID.
|
# - 1 if some music of that artist is locally available
|
||||||
|
|
||||||
|
@include "lib/awk/lib.awk"
|
||||||
|
|
||||||
BEGIN {
|
BEGIN {
|
||||||
OFS="\t"
|
OFS="\t"
|
||||||
local_artists[0] = 0
|
flagged[0] = 0
|
||||||
delete local_artists[0]
|
delete flagged[0]
|
||||||
if (file_local_artists) {
|
if (flagfile) {
|
||||||
while ((getline < file_local_artists) == 1)
|
while ((getline < flagfile) == 1)
|
||||||
local_artists[$1] = 1
|
flagged[$1] = 1
|
||||||
close(file_local_artists)
|
close(flagfile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
gsub("&", "\\\\&")
|
# Read data
|
||||||
name = $2 == "Group" ? format_group : format_person
|
line = format
|
||||||
l = local_artists[$1] ? format_local : ""
|
mbid = $1
|
||||||
if ($4)
|
type = $2
|
||||||
name = name " " format_disambiguation
|
name = $3 ? sprintf(fmtname, escape($3)) : ""
|
||||||
sub("<<disambiguation>>", $4, name)
|
sort = 0
|
||||||
sub("<<name>>", $3, name)
|
if (sortby) {
|
||||||
print l, name, "0", $1
|
sort = sortby == "sort-artist-sortname" ? $4 : $3
|
||||||
|
}
|
||||||
|
disa = $5 ? sprintf(fmtdisambiguation, escape($5)) : ""
|
||||||
|
# Transform data and fill placeholders
|
||||||
|
if (flagged[mbid])
|
||||||
|
gsub("<<flag>>", flag_local, line)
|
||||||
|
else
|
||||||
|
gsub("<<flag>>", flag_nolocal, line)
|
||||||
|
if (type == "Group")
|
||||||
|
gsub("<<type>>", type_group, line)
|
||||||
|
else
|
||||||
|
gsub("<<type>>", type_person, line)
|
||||||
|
gsub("<<name>>", name, line)
|
||||||
|
gsub("<<disambiguation>>", disa, line)
|
||||||
|
print line, sort, "0", mbid, flagged[mbid]
|
||||||
}
|
}
|
||||||
|
|||||||
100
src/awk/preview_artist.awk
Normal file
100
src/awk/preview_artist.awk
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
# Preview artists
|
||||||
|
#
|
||||||
|
# parameters:
|
||||||
|
# name | Artist name
|
||||||
|
# sortname | Artist sort name
|
||||||
|
# disamb | Artist disambiguation string
|
||||||
|
# bio | Artist biography
|
||||||
|
# alias | Tab-delimited string of aliases
|
||||||
|
# startdate | Date where artist is born, group is founded
|
||||||
|
# startplace | Place where artist is born, group is founded
|
||||||
|
# enddate | Date where artist died, group dissolved
|
||||||
|
# endplace | Place where artist died, group dissolved
|
||||||
|
# url | Tab-delimited string of ;-delimited pairs (url name, url link)
|
||||||
|
#
|
||||||
|
# theme parameters (see `src/sh/theme.sh`)
|
||||||
|
# format | Format string
|
||||||
|
# fmtname | `printf` expression to transform artist names
|
||||||
|
# fmtsortname | `printf` expression to transform artist sortnames
|
||||||
|
# fmtbio | `printf` expression to transform disambiguation
|
||||||
|
# fmtdisamb | `printf` expression to transform disambiguation
|
||||||
|
# fmtalias | `printf` expression to transform alias
|
||||||
|
# join_alias | `printf` expression to join one alias to the previously constructed aliases
|
||||||
|
# format_start | Format string for born/founded string
|
||||||
|
# fmtstart | `printf` expression for born/founded
|
||||||
|
# fmtstart_startdate | `printf` expression to transform the start date
|
||||||
|
# fmtstart_startplace | `printf` expression to transform the start place
|
||||||
|
# format_end | Format string for died/dissolved string
|
||||||
|
# fmtend | `printf` expression for died/dissolved
|
||||||
|
# fmtend_enddate | `printf` expression to transform the end date
|
||||||
|
# fmtend_endplace | `printf` expression to transform the end place
|
||||||
|
# fmturl | `printf` expression for links
|
||||||
|
# format_url | Format string for url string
|
||||||
|
# join_url | `printf` expression to join one url to all others
|
||||||
|
# fmturl_urlindex | `printf` expression for URL index
|
||||||
|
# fmturl_urlname | `printf` expression for URL name
|
||||||
|
# fmturl_urllink | `printf` expression for URL link (address)
|
||||||
|
#
|
||||||
|
# This awk program takes no input from stdin and outputs the preview text for
|
||||||
|
# the artist.
|
||||||
|
|
||||||
|
@include "lib/awk/lib.awk"
|
||||||
|
|
||||||
|
BEGIN {
|
||||||
|
name = name ? sprintf(fmtname, escape(name)) : ""
|
||||||
|
sortname = sortname ? sprintf(fmtsortname, escape(sortname)) : ""
|
||||||
|
disamb = disamb ? sprintf(fmtdisamb, escape(disamb)) : ""
|
||||||
|
bio = bio ? sprintf(fmtbio, escape(bio)) : ""
|
||||||
|
# Alias
|
||||||
|
if (alias) {
|
||||||
|
split(alias, a, "\t")
|
||||||
|
for (i in a) {
|
||||||
|
alias = i == 1 ? a[i] : sprintf(join_alias, alias, a[i])
|
||||||
|
}
|
||||||
|
alias = sprintf(fmtalias, escape(alias))
|
||||||
|
}
|
||||||
|
# Start
|
||||||
|
startdate = startdate ? sprintf(fmtstart_startdate, escape(startdate)) : ""
|
||||||
|
startplace = startplace ? sprintf(fmtstart_startplace, escape(startplace)) : ""
|
||||||
|
if (startdate || startplace) {
|
||||||
|
gsub("<<startdate>>", startdate, format_start)
|
||||||
|
gsub("<<startplace>>", startplace, format_start)
|
||||||
|
start = sprintf(fmtstart, escape(format_start))
|
||||||
|
}
|
||||||
|
# End
|
||||||
|
enddate = enddate ? sprintf(fmtend_enddate, escape(enddate)) : ""
|
||||||
|
endplace = endplace ? sprintf(fmtend_endplace, escape(endplace)) : ""
|
||||||
|
if (enddate || endplace) {
|
||||||
|
gsub("<<enddate>>", enddate, format_end)
|
||||||
|
gsub("<<endplace>>", endplace, format_end)
|
||||||
|
end = sprintf(fmtend, escape(format_end))
|
||||||
|
}
|
||||||
|
# Links
|
||||||
|
if (url) {
|
||||||
|
split(url, a, "\t")
|
||||||
|
for (i in a) {
|
||||||
|
urlindex = sprintf(fmturl_urlindex, i)
|
||||||
|
pos = index(a[i], ";")
|
||||||
|
urlname = substr(a[i], 1, pos - 1)
|
||||||
|
urlname = urlname ? sprintf(fmturl_urlname, escape(urlname)) : ""
|
||||||
|
urllink = substr(a[i], pos + 1)
|
||||||
|
urllink = urllink ? sprintf(fmturl_urllink, escape(urllink)) : ""
|
||||||
|
urlentry = format_url
|
||||||
|
gsub("<<urlindex>>", urlindex, urlentry)
|
||||||
|
gsub("<<urlname>>", urlname, urlentry)
|
||||||
|
gsub("<<urllink>>", urllink, urlentry)
|
||||||
|
url = i == 1 ? urlentry : sprintf(join_url, url, urlentry)
|
||||||
|
}
|
||||||
|
url = sprintf(fmturl, escape(url))
|
||||||
|
}
|
||||||
|
# Combine all and print
|
||||||
|
gsub("<<name>>", name, format)
|
||||||
|
gsub("<<sortname>>", sortname, format)
|
||||||
|
gsub("<<disambiguation>>", disamb, format)
|
||||||
|
gsub("<<bio>>", bio, format)
|
||||||
|
gsub("<<alias>>", alias, format)
|
||||||
|
gsub("<<start>>", start, format)
|
||||||
|
gsub("<<end>>", end, format)
|
||||||
|
gsub("<<url>>", url, format)
|
||||||
|
print format
|
||||||
|
}
|
||||||
@@ -1,62 +1,62 @@
|
|||||||
# List recordings
|
# List release groups
|
||||||
#
|
#
|
||||||
# parameter file_local_recordings: This is an optional parameter with the path
|
# flagfile Path to a file with a MusicBrainz track ID per line, tab-delimited
|
||||||
# to a file with a MusicBrainz recording ID
|
# from the path to the decoration file (optional)
|
||||||
# per line.
|
#
|
||||||
# parameter format: The format of a recording line including the
|
# theme parameters (see `src/sh/awk.sh` and `src/sh/theme.sh`)
|
||||||
# placeholders <<med>> for medium number,
|
# format Format string
|
||||||
# <<nr> for for track number within a medium,
|
# flag_local Flag for locally available music
|
||||||
# <<title>> for the title, <<artist>> for the
|
# flag_nolocal Flag for locally unavailable music
|
||||||
# artist string, and <<duration>> for the
|
# playing_yes Mark for currently playing track
|
||||||
# track duration.
|
# playing_no Mark for currently not playing track
|
||||||
# parameter format_local: String to indicate that the track is locally
|
# fmtmedia `printf` expression for media identifier
|
||||||
# available
|
# fmtnr `printf` expression for track number
|
||||||
# parameter format_current: String to indicate that the track is
|
# fmttitle `printf` expression for title
|
||||||
# "currently playing"
|
# fmtartist `printf` expression for artist
|
||||||
# parameter current_id: MusicBrainz track ID of a track to be marked
|
# fmtduration `printf` expression track duration
|
||||||
# as "currently playing"
|
|
||||||
#
|
#
|
||||||
# The input to this awk program is a sequence of lines containing the following fields:
|
# The input to this awk program is a sequence of lines containing the following fields:
|
||||||
# Field 1: The MusicBrainz ID of the release this track belongs to
|
# Field 1: The MusicBrainz ID of the release this track belongs to
|
||||||
# Field 2: MusicBrainz ID of this track
|
# Field 2: MusicBrainz ID of this track
|
||||||
# Field 3: Number of media of theis release
|
# Field 3: Number of media of this release
|
||||||
# Field 4: Medium number of this track within the release
|
# Field 4: Medium number of this track within the release
|
||||||
# Field 5: Track number of this track within the medium
|
# Field 5: Track number of this track within the medium
|
||||||
# Field 6: Duration of this track in miliseconds
|
# Field 6: Duration of this track in milliseconds
|
||||||
# Field 7: Title of this track
|
# Field 7: Title of this track
|
||||||
# Field 8: Artist of this track
|
# Field 8: Artist of this track
|
||||||
# Field 9: Path to decoratoin file of this release
|
# Field 9: Path to decoration file of this release
|
||||||
|
# Field 10: Empty outside of playlists, else "yes" if the track is currently
|
||||||
|
# being played, and something else otherwise.
|
||||||
#
|
#
|
||||||
# The output is a sequence of tab-delimited lines containing the following fields:
|
# The output of this script is a sequence of tab-delimited lines. The first
|
||||||
# Field 1: Sort value (to sort the track within the release)
|
# `REC_FMT_CNT` fields are those that will be displayed to the user. The
|
||||||
# Field 2: The string `format_local` if the track is locally available
|
# following fields are
|
||||||
# Field 3: The string `format_current` if the track has MusicBrainz ID `current_id`
|
# - Constant 0 (we will not sort)
|
||||||
# Field 4: The track line to be displayed according to `format`
|
# - MusicBrainz release ID if specified, else the constant "0"
|
||||||
# Field 5: The MusicBrainz ID of the release this track belongs to
|
# - MusicBrainz track ID
|
||||||
# Field 6: The MusicBrainz ID of this track ":" separated from the path to the
|
# - Path to decoration file if some music of that release is locally available
|
||||||
# decoration file of this release
|
|
||||||
|
@include "lib/awk/lib.awk"
|
||||||
|
|
||||||
BEGIN {
|
BEGIN {
|
||||||
OFS="\t"
|
OFS="\t"
|
||||||
local_recordings[0] = 0
|
flagged[0] = 0
|
||||||
delete local_recordings[0]
|
delete flagged[0]
|
||||||
if (file_local_recordings) {
|
if (flagfile) {
|
||||||
while ((getline < file_local_recordings) == 1)
|
while ((getline < flagfile) == 1)
|
||||||
local_recordings[$1] = 1
|
flagged[$1] = 1
|
||||||
close(file_local_recordings)
|
close(flagfile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
parentid = $1
|
# Read data
|
||||||
id = $2
|
line = format
|
||||||
medtot = $3
|
releaseid = $1
|
||||||
med = $4
|
mbid = $2
|
||||||
nr = $5
|
medtot = $3 + 0
|
||||||
|
med = ($4 && medtot >= 2) ? sprintf(fmtmedia, escape($4)) : ""
|
||||||
|
nr = $5 ? sprintf(fmtnr, escape($5)) : ""
|
||||||
dur = $6
|
dur = $6
|
||||||
title = $7
|
|
||||||
artist = $8
|
|
||||||
deco = local_recordings[id] ? $9 : ""
|
|
||||||
gsub("&", "\\\\&", title)
|
|
||||||
gsub("&", "\\\\&", artist)
|
|
||||||
# Parse duration
|
# Parse duration
|
||||||
if (dur) {
|
if (dur) {
|
||||||
dur = int(dur / 1000)
|
dur = int(dur / 1000)
|
||||||
@@ -66,21 +66,33 @@ BEGIN {
|
|||||||
ds = dur % 60
|
ds = dur % 60
|
||||||
if (ds <= 9)
|
if (ds <= 9)
|
||||||
ds = "0"ds
|
ds = "0"ds
|
||||||
|
if (dh && dm <= 9)
|
||||||
|
dm = "0"dm
|
||||||
dur = dh ? dh":"dm":"ds : dm":"ds
|
dur = dh ? dh":"dm":"ds : dm":"ds
|
||||||
} else {
|
} else {
|
||||||
dur = "??:??"
|
dur = "??:??"
|
||||||
}
|
}
|
||||||
line = format
|
dur = sprintf(fmtduration, dur)
|
||||||
if (medtot == 1)
|
title = $7 ? sprintf(fmttitle, escape($7)) : ""
|
||||||
sub("<<med>>", "", line)
|
artist = $8 ? sprintf(fmtartist, escape($8)) : ""
|
||||||
|
current = $10
|
||||||
|
if (current || (flagged[mbid] && $9))
|
||||||
|
flagged[mbid] = $9
|
||||||
|
# Transform data and fill placeholders
|
||||||
|
if (flagged[mbid])
|
||||||
|
gsub("<<flag>>", flag_local, line)
|
||||||
else
|
else
|
||||||
sub("<<med>>", med, line)
|
gsub("<<flag>>", flag_nolocal, line)
|
||||||
sub("<<nr>>", nr, line)
|
gsub("<<media>>", med, line)
|
||||||
sub("<<title>>", title, line)
|
gsub("<<nr>>", nr, line)
|
||||||
sub("<<artist>>", artist, line)
|
gsub("<<title>>", title, line)
|
||||||
sub("<<duration>>", dur, line)
|
gsub("<<artist>>", artist, line)
|
||||||
l = local_recordings[id] ? format_local : ""
|
gsub("<<duration>>", dur, line)
|
||||||
c = id == current_id ? format_current : ""
|
if (current) {
|
||||||
sortk = med" "nr
|
if (current == "yes")
|
||||||
print sortk, l, c, line, parentid, id ":" deco
|
gsub("<<playing>>", playing_yes, line)
|
||||||
|
else
|
||||||
|
gsub("<<playing>>", playing_no, line)
|
||||||
|
}
|
||||||
|
print line, "0", releaseid ? releaseid : "0", mbid, flagged[mbid] ? flagged[mbid] : ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,48 +1,37 @@
|
|||||||
# List release groups
|
# List release groups
|
||||||
#
|
#
|
||||||
# parameter file_local_releasegroups: This is an optional parameter with the
|
# flagfile path to a file with a MusicBrainz release-group ID per line (optional)
|
||||||
# path to a file with a MusicBrainz
|
# sortby sort selector (see `src/sh/awk.sh`)
|
||||||
# release-group ID per line.
|
# origartist Artist name to compare release-groups (optional)
|
||||||
# parameter format_release: Format for the release title with a
|
# artistid MusicBrainz ID of the artist (optional)
|
||||||
# <<title>> placeholder.
|
#
|
||||||
# parameter format_release_w_artist: Same as `format_release` but with an
|
# theme parameters (see `src/sh/awk.sh` and `src/sh/theme.sh`)
|
||||||
# additional <<artist>> placeholder.
|
# format Format string
|
||||||
# parameter format_year: Format string for the year part, with a
|
# flag_local Flag for locally available music
|
||||||
# <<year>> placeholder.
|
# flag_nolocal Flag for locally unavailable music
|
||||||
# parameter format_local: String to indicate that the track is
|
# type_single Single
|
||||||
# locally available.
|
# type_album LP
|
||||||
# parameter artist: Artist name to compare release-groups
|
# type_ep EP
|
||||||
# artist names against. If the names
|
# type_broadcast Broadcast
|
||||||
# differ, then the format with <<artist>>
|
# type_other Other type
|
||||||
# placeholder is used (optional)
|
# type_unknown Type unknown
|
||||||
# parameter artistid MusicBrainz ID of the artist (optional).
|
# hassecondary_yes Release group has secondary type(s)
|
||||||
# Then, there are several format strings that indicate the type of a release
|
# hassecondary_no Release group does not have any secondary type
|
||||||
# group. The types are implicit from the parameter names:
|
# fmtsecondary `printf` expression to display secondary type
|
||||||
# parameter format_album
|
# secondary_soundtrack ...
|
||||||
# parameter format_single
|
# secondary_spokenword ...
|
||||||
# parameter format_ep
|
# secondary_interview ...
|
||||||
# parameter format_broadcast
|
# secondary_audiobook ...
|
||||||
# parameter format_other
|
# secondary_audiodrama ...
|
||||||
# Some release groups have also a secondary type. The presence of a secondary
|
# secondary_live ...
|
||||||
# type is formatted using
|
# secondary_remix ...
|
||||||
# parameter format_secondary.
|
# secondary_djmix ...
|
||||||
# The list of all secondary types (implicit from their variable names) are
|
# secondary_mixtape ...
|
||||||
# formatted using
|
# secondary_demo ...
|
||||||
# parameter format_secondary.
|
# secondary_fieldrec ...
|
||||||
# Each of the secondary types is specified with (the type is implicit from the
|
# fmttitle `printf` expression to transform title
|
||||||
# variable names)
|
# fmtartist `printf` expression to transform artist
|
||||||
# parameter format_compilation
|
# fmtyear `printf` expression to transform year
|
||||||
# parameter format_soundtrack
|
|
||||||
# parameter format_spokenword
|
|
||||||
# parameter format_interview
|
|
||||||
# parameter format_audiobook
|
|
||||||
# parameter format_audiodrama
|
|
||||||
# parameter format_live
|
|
||||||
# parameter format_remix
|
|
||||||
# parameter format_djmix
|
|
||||||
# parameter format_mixtape
|
|
||||||
# parameter format_demo
|
|
||||||
# parameter format_fieldrec
|
|
||||||
#
|
#
|
||||||
# The input to this awk program is a sequence of lines containing the following
|
# The input to this awk program is a sequence of lines containing the following
|
||||||
# fields:
|
# fields:
|
||||||
@@ -53,76 +42,83 @@
|
|||||||
# Field 5: Title of the release group
|
# Field 5: Title of the release group
|
||||||
# Field 6: The artist as credited
|
# Field 6: The artist as credited
|
||||||
#
|
#
|
||||||
# The output is a sequence of tab-delimited lines with the fields:
|
# The output of this script is a sequence of tab-delimited lines. The first
|
||||||
# Field 1: Sort value to sort release groups
|
# `RGV_FMT_CNT` fields are those that will be displayed to the user. The
|
||||||
# Field 2: The flag `format_local` if the release group is accessible locally,
|
# following fields are
|
||||||
# and "" else.
|
# - sort key (release year)
|
||||||
# Field 3: Release-group type
|
# - MusicBrainz artist ID if specified, else the constant "0"
|
||||||
# Field 4: Release-group string
|
# - MusicBrainz release-group ID
|
||||||
# Field 5: Release-group year
|
# - 1 if some music of that release group is locally available
|
||||||
# Field 6: Secondary types
|
|
||||||
# Field 7: MusicBrainz artist ID of the release group artist, if there is one,
|
@include "lib/awk/lib.awk"
|
||||||
# else "0"
|
|
||||||
# Field 8: MusicBrainz release-group ID
|
|
||||||
BEGIN {
|
BEGIN {
|
||||||
OFS="\t"
|
OFS="\t"
|
||||||
local_releasegroups[0] = 0
|
flagged[0] = 0
|
||||||
delete local_releasegroups[0]
|
delete flagged[0]
|
||||||
if (file_local_releasegroups) {
|
if (flagfile) {
|
||||||
while ((getline < file_local_releasegroups) == 1)
|
while ((getline < flagfile) == 1)
|
||||||
local_releasegroups[$1] = 1
|
flagged[$1] = 1
|
||||||
close(file_local_releasegroups)
|
close(flagfile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
line_type = ""
|
# Read data
|
||||||
line_sectype = ""
|
line = format
|
||||||
line_year = ""
|
mbid = $1
|
||||||
gsub("&", "\\\\&")
|
|
||||||
id = $1
|
|
||||||
type = $2
|
type = $2
|
||||||
sectype = $3
|
sectype = $3
|
||||||
year = substr($4, 1, 4) + 0
|
year = $4 ? sprintf(fmtyear, substr($4, 1, 4) + 0) : ""
|
||||||
title = $5
|
title = $5 ? sprintf(fmttitle, escape($5)) : ""
|
||||||
artistcredit = $6
|
artist = escape($6) != origartist ? sprintf(fmtartist, escape($6)) : ""
|
||||||
line_release = artist == artistcredit ? format_release : format_release_w_artist
|
sort = $4 ? -$4 : 0
|
||||||
l = local_releasegroups[$1] ? format_local : ""
|
sort = 0
|
||||||
switch (type) {
|
if (sortby) {
|
||||||
case "Single": line_type=format_single; break
|
sort = sortby == "sort-rg-year" ? ($4 ? -$4 : 0) : $5
|
||||||
case "Album": line_type=format_album; break
|
|
||||||
case "EP": line_type=format_ep; break
|
|
||||||
case "Broadcast": line_type=format_broadcast; break
|
|
||||||
case "Other": line_type=format_other; break
|
|
||||||
default: line_type=""
|
|
||||||
}
|
}
|
||||||
|
# Transform data and fill placeholders
|
||||||
|
if (flagged[mbid])
|
||||||
|
gsub("<<flag>>", flag_local, line)
|
||||||
|
else
|
||||||
|
gsub("<<flag>>", flag_nolocal, line)
|
||||||
|
switch (type) {
|
||||||
|
case "Single": t = type_single; break
|
||||||
|
case "Album": t = type_album; break
|
||||||
|
case "EP": t = type_ep; break;
|
||||||
|
case "Broadcast": t = type_broadcast; break
|
||||||
|
case "Other": t = type_other; break
|
||||||
|
default: t = type_unknown; break
|
||||||
|
}
|
||||||
|
gsub("<<type>>", t, line)
|
||||||
|
if (sectype)
|
||||||
|
gsub("<<hassecondary>>", hassecondary_yes, line)
|
||||||
|
else
|
||||||
|
gsub("<<hassecondary>>", hassecondary_no, line)
|
||||||
|
gsub("<<title>>", title, line)
|
||||||
|
gsub("<<artist>>", artist, line)
|
||||||
|
gsub("<<year>>", year, line)
|
||||||
|
t = ""
|
||||||
|
s = ""
|
||||||
split(sectype, a, ";")
|
split(sectype, a, ";")
|
||||||
for (i in a) {
|
for (i in a) {
|
||||||
t=""
|
|
||||||
switch (a[i]) {
|
switch (a[i]) {
|
||||||
case "Compilation": t=format_compilation; break
|
case "Compilation": t = secondary_compilation; break
|
||||||
case "Soundtrack": t=format_soundtrack; break
|
case "Soundtrack": t = secondary_soundtrack; break
|
||||||
case "Spokenword": t=format_spokenword; break
|
case "Spokenword": t = secondary_spokenword; break
|
||||||
case "Interview": t=format_interview; break
|
case "Interview": t = secondary_interview; break
|
||||||
case "Audiobook": t=format_audiobook; break
|
case "Audiobook": t = secondary_audiobook; break
|
||||||
case "Audio drama": t=format_audiodrama; break
|
case "Audio drama": t = secondary_audiodrama; break
|
||||||
case "Live": t=format_live; break
|
case "Live": t = secondary_live; break
|
||||||
case "Remix": t=format_remix; break
|
case "Remix": t = secondary_remix; break
|
||||||
case "DJ-mix": t=format_djmix; break
|
case "DJ-mix": t = secondary_djmix; break
|
||||||
case "Mixtape/Street": t=format_mixtape; break
|
case "Mixtape/Street": t = secondary_mixtape; break
|
||||||
case "Demo": t=format_demo; break
|
case "Demo": t = secondary_demo; break
|
||||||
case "Field recording": t=fieldrec; break
|
case "Field recording": t = secondary_fieldrec; break
|
||||||
}
|
}
|
||||||
if (t)
|
if (t)
|
||||||
line_sectype=line_sectype ? line_sectype ", " t : t
|
s = s ? s ", " t : t
|
||||||
}
|
}
|
||||||
if (sectype) {
|
s = s ? sprintf(fmtsecondary, s) : ""
|
||||||
line_type = sprintf(format_has_secondary, line_type)
|
gsub("<<secondary>>", s, line)
|
||||||
line_sectype = sprintf(format_secondary, line_sectype)
|
print line, sort, artistid ? artistid : "0", mbid, flagged[mbid]
|
||||||
}
|
|
||||||
sub("<<title>>", title, line_release)
|
|
||||||
sub("<<artist>>", artistcredit, line_release)
|
|
||||||
line_year = year ? format_year : ""
|
|
||||||
sub("<<year>>", year, line_year)
|
|
||||||
sortk = year ? year : 0
|
|
||||||
print sortk, l, line_type, line_release, line_year, line_sectype, artistid ? artistid : "0", id
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +1,31 @@
|
|||||||
# List releases
|
# List release groups
|
||||||
#
|
#
|
||||||
# parameter file_local_releases: This is an optional parameter with the
|
# flagfile path to a file with a MusicBrainz release ID per line,
|
||||||
# path to a file with a MusicBrainz
|
# tab-delimited from the path to the decoration file
|
||||||
# release ID per line.
|
# (optional)
|
||||||
# parameter format_release: Format for the release with the
|
# origtitle Title of release group (optional)
|
||||||
# placeholders <<status>>, <<tracks>>,
|
# origartist Artist credit of release group (optional)
|
||||||
# <<media>>, <<year>>, <<country>>, and
|
# releasegroupid MusicBrainz release-group ID (optional)
|
||||||
# <<label>>.
|
#
|
||||||
# parameter format_release_title_artist: Format to specify title and artist,
|
# theme parameters (see `src/sh/awk.sh` and `src/sh/theme.sh`)
|
||||||
# with the placeholders <<title>> and
|
# format Format string
|
||||||
# <<artist>>.
|
# flag_local Flag for locally available music
|
||||||
# parameter format_release_title: Format to specify the release title
|
# flag_nolocal Flag for locally unavailable music
|
||||||
# with a placeholder <<title>>.
|
# status_official Official release
|
||||||
# parameter format_release_artist: Format to specify the release artist
|
# status_promo Promotional release
|
||||||
# with a placeholder <<artist>>.
|
# status_bootleg Bootleg release
|
||||||
# parameter format_local: String to indicate that the track is
|
# status_pseudo Pseudo release
|
||||||
# locally available.
|
# status_withdrawn Withdrawn
|
||||||
# parameter rg_artist: Artist name of release group
|
# status_expunged Expunged release
|
||||||
# (optional)
|
# status_cancelled Cancelled release
|
||||||
# parameter rg_title: Title of release group (optional)
|
# status_unknown Status of release is not specified
|
||||||
# parameter rgid: MusicBrainz release-group ID
|
# fmttracks `printf` expression for track number
|
||||||
# (optional)
|
# fmtmedia `printf` expression for media number
|
||||||
# Then, there are several format strings that indicate the status of a release.
|
# fmtyear `printf` expression for release year
|
||||||
# The status are implicit from the parameter names:
|
# fmtcountry `printf` expression for release country
|
||||||
# parameter release_official
|
# fmtlabel `printf` expression for label
|
||||||
# parameter release_promotion
|
# fmttitle `printf` expression for release title
|
||||||
# parameter release_bootleg
|
# fmtartist `printf` expression for release artist credits
|
||||||
# parameter release_pseudo
|
|
||||||
# parameter release_withdrawn
|
|
||||||
# parameter release_expunged
|
|
||||||
# parameter release_cancelled
|
|
||||||
#
|
#
|
||||||
# The input to this awk program is a sequence of lines containing the following
|
# The input to this awk program is a sequence of lines containing the following
|
||||||
# fields:
|
# fields:
|
||||||
@@ -44,68 +40,62 @@
|
|||||||
# Field 9: Release title
|
# Field 9: Release title
|
||||||
# Field 10: Artist as credited
|
# Field 10: Artist as credited
|
||||||
#
|
#
|
||||||
# The output is a sequence of tab-delimited lines with the fields:
|
# The output of this script is a sequence of tab-delimited lines. The first
|
||||||
# Field 1: Sort value to sort release groups
|
# `RV_FMT_CNT` fields are those that will be displayed to the user. The
|
||||||
# Field 2: The flag `format_local` if the release is accessible locally, and ""
|
# following fields are
|
||||||
# else.
|
# - sort key (release year)
|
||||||
# Field 3: Release line
|
# - MusicBrainz release-group ID if specified, else the constant "0"
|
||||||
# Field 4: MusicBrainz release-group ID if present, else "0"
|
# - MusicBrainz release ID
|
||||||
# Field 5: MusicBrainz release ID followed by ":" and then a path to the
|
# - Path to decoration file if some music of that release is locally available
|
||||||
# decoration file (if it exists)
|
|
||||||
|
@include "lib/awk/lib.awk"
|
||||||
|
|
||||||
BEGIN {
|
BEGIN {
|
||||||
OFS="\t"
|
OFS="\t"
|
||||||
local_releases[0] = 0
|
flagged[0] = 0
|
||||||
delete local_releases[0]
|
delete flagged[0]
|
||||||
if (file_local_releases) {
|
if (flagfile) {
|
||||||
while ((getline < file_local_releases) == 1)
|
while ((getline < flagfile) == 1)
|
||||||
local_releases[$1] = $2
|
flagged[$1] = $2
|
||||||
close(file_local_releases)
|
close(flagfile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
id = $1
|
# Read data
|
||||||
|
line = format
|
||||||
|
mbid = $1
|
||||||
status = $2
|
status = $2
|
||||||
year = substr($3, 1, 4) + 0
|
year = $3 ? sprintf(fmtyear, substr($3, 1, 4) + 0) : ""
|
||||||
year = year == 0 ? "" : year
|
|
||||||
covercount = $4
|
covercount = $4
|
||||||
label = $5
|
label = $5 ? sprintf(fmtlabel, escape($5)) : ""
|
||||||
trackcnt = $6
|
tracks = $6 ? sprintf(fmttracks, escape($6)) : ""
|
||||||
media = $7
|
media = $7 ? sprintf(fmtmedia, escape($7)) : ""
|
||||||
country = $8
|
country = $8 ? sprintf(fmtcountry, escape($8)) : ""
|
||||||
title = $9
|
title = escape($9) != origtitle ? sprintf(fmttitle, escape($9)) : ""
|
||||||
artist = $10
|
artist = escape($10) != origartist ? sprintf(fmtartist, escape($10)) : ""
|
||||||
switch (status) {
|
sort = $3 + 0
|
||||||
case "Official": line_status = release_official; break
|
# Transform data and fill placeholders
|
||||||
case "Promotion": line_status = release_promotion; break
|
if (flagged[mbid])
|
||||||
case "Bootleg": line_status = release_bootleg; break
|
gsub("<<flag>>", flag_local, line)
|
||||||
case "Pseudo-release": line_status = release_pseudo; break
|
|
||||||
case "Withdrawn": line_status = release_withdrawn; break
|
|
||||||
case "Expunged": line_status = release_expunged; break
|
|
||||||
case "Cancelled": line_status = release_cancelled; break
|
|
||||||
default: line_status = ""
|
|
||||||
}
|
|
||||||
line = format_release
|
|
||||||
if (artist != rg_artist && title != rg_title)
|
|
||||||
line = line "\t" format_release_title_artist
|
|
||||||
else if (artist != rg_artist && title == rg_title)
|
|
||||||
line = line "\t" format_release_artist
|
|
||||||
else if (artist == rg_artist && title != rg_title)
|
|
||||||
line = line "\t" format_release_title
|
|
||||||
else
|
else
|
||||||
line = line "\t"
|
gsub("<<flag>>", flag_nolocal, line)
|
||||||
|
switch (status) {
|
||||||
gsub("<<status>>", line_status, line)
|
case "Official": s = status_official; break
|
||||||
gsub("<<year>>", year, line)
|
case "Promotion": s = status_promotion; break
|
||||||
gsub("<<tracks>>", trackcnt, line)
|
case "Bootleg": s = status_bootleg; break
|
||||||
|
case "Pseudo-release": s = status_pseudo; break
|
||||||
|
case "Withdrawn": s = status_withdrawn; break
|
||||||
|
case "Expunged": s = status_expunged; break
|
||||||
|
case "Cancelled": s = status_cancelled; break
|
||||||
|
default: s = status_unknown
|
||||||
|
}
|
||||||
|
gsub("<<status>>", s, line)
|
||||||
|
gsub("<<tracks>>", tracks, line)
|
||||||
gsub("<<media>>", media, line)
|
gsub("<<media>>", media, line)
|
||||||
gsub("&", "\\\\&", label)
|
gsub("<<year>>", year, line)
|
||||||
gsub("<<label>>", label, line)
|
|
||||||
gsub("&", "\\\\&", title)
|
|
||||||
gsub("<<title>>", title, line)
|
|
||||||
gsub("&", "\\\\&", artist)
|
|
||||||
gsub("<<artist>>", artist, line)
|
|
||||||
gsub("<<country>>", country, line)
|
gsub("<<country>>", country, line)
|
||||||
sortk = year ? year : 0
|
gsub("<<label>>", label, line)
|
||||||
l = local_releases[id] ? format_local : ""
|
gsub("<<title>>", title, line)
|
||||||
print sortk, l, line, rgid ? rgid : "0", id ":" local_releases[id]
|
gsub("<<artist>>", artist, line)
|
||||||
|
print line, sort, releasegroupid ? releasegroupid : "0", mbid, flagged[mbid] ? flagged[mbid] : ""
|
||||||
}
|
}
|
||||||
|
|||||||
7
src/lib/awk/lib.awk
Normal file
7
src/lib/awk/lib.awk
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Awk methods commonly used
|
||||||
|
|
||||||
|
# Escape string
|
||||||
|
function escape(s) {
|
||||||
|
gsub("&", "\\\\&", s)
|
||||||
|
return s
|
||||||
|
}
|
||||||
327
src/main.sh
327
src/main.sh
@@ -36,6 +36,8 @@ VIEW_LIST_ARTISTS="list-artists"
|
|||||||
VIEW_LIST_ALBUMS="list-albums"
|
VIEW_LIST_ALBUMS="list-albums"
|
||||||
VIEW_SELECT_ARTIST="select-artist"
|
VIEW_SELECT_ARTIST="select-artist"
|
||||||
VIEW_PLAYLIST="playlist"
|
VIEW_PLAYLIST="playlist"
|
||||||
|
VIEW_PLAYLIST_PLAYLISTSTORE="playlist-list"
|
||||||
|
VIEW_PLAYLIST_STORE="playlist-store"
|
||||||
VIEW_QUIT="quit"
|
VIEW_QUIT="quit"
|
||||||
MODE_NORMAL="hidden"
|
MODE_NORMAL="hidden"
|
||||||
MODE_INSERT="show"
|
MODE_INSERT="show"
|
||||||
@@ -47,21 +49,27 @@ MODE_INSERT="show"
|
|||||||
# Load logging methods
|
# Load logging methods
|
||||||
. "sh/log.sh"
|
. "sh/log.sh"
|
||||||
|
|
||||||
|
# Load configuration
|
||||||
|
. "sh/config.sh"
|
||||||
|
|
||||||
|
# Load mpv methods
|
||||||
|
. "sh/mpv.sh"
|
||||||
|
|
||||||
# Load query methods
|
# Load query methods
|
||||||
. "sh/query.sh"
|
. "sh/query.sh"
|
||||||
|
|
||||||
# Load playback helper
|
# Load local file handling
|
||||||
. "sh/playback.sh"
|
. "sh/local.sh"
|
||||||
|
|
||||||
# Load playlist tools
|
# Load playlist tools
|
||||||
. "sh/playlist.sh"
|
. "sh/playlist.sh"
|
||||||
|
|
||||||
|
# Load playback helper
|
||||||
|
. "sh/playback.sh"
|
||||||
|
|
||||||
# Load MusicBrainz, Discogs, and wiki methods
|
# Load MusicBrainz, Discogs, and wiki methods
|
||||||
. "sh/api.sh"
|
. "sh/api.sh"
|
||||||
|
|
||||||
# Load mpv methods
|
|
||||||
. "sh/mpv.sh"
|
|
||||||
|
|
||||||
# Load preview methods
|
# Load preview methods
|
||||||
. "sh/preview.sh"
|
. "sh/preview.sh"
|
||||||
|
|
||||||
@@ -71,9 +79,6 @@ MODE_INSERT="show"
|
|||||||
# Load MusicBrainz wrappers
|
# Load MusicBrainz wrappers
|
||||||
. "sh/mb.sh"
|
. "sh/mb.sh"
|
||||||
|
|
||||||
# Load local file handling
|
|
||||||
. "sh/local.sh"
|
|
||||||
|
|
||||||
# Load list-generating methods
|
# Load list-generating methods
|
||||||
. "sh/lists.sh"
|
. "sh/lists.sh"
|
||||||
|
|
||||||
@@ -83,6 +88,24 @@ MODE_INSERT="show"
|
|||||||
# Load keys
|
# Load keys
|
||||||
. "sh/keys.sh"
|
. "sh/keys.sh"
|
||||||
|
|
||||||
|
# Load sorting methods
|
||||||
|
. "sh/sort.sh"
|
||||||
|
|
||||||
|
# Load theme
|
||||||
|
. "sh/theme.sh"
|
||||||
|
|
||||||
|
# Load tools
|
||||||
|
. "sh/tools.sh"
|
||||||
|
|
||||||
|
# Load AWK scripts
|
||||||
|
. "sh/awk.sh"
|
||||||
|
|
||||||
|
# Load filters
|
||||||
|
. "sh/filter.sh"
|
||||||
|
|
||||||
|
# Load lyrics support
|
||||||
|
. "sh/lyrics.sh"
|
||||||
|
|
||||||
# Command-line options that may only be used internally.
|
# Command-line options that may only be used internally.
|
||||||
# --lines
|
# --lines
|
||||||
# --playback
|
# --playback
|
||||||
@@ -95,6 +118,8 @@ MODE_INSERT="show"
|
|||||||
# --preview
|
# --preview
|
||||||
# --show-keybindings
|
# --show-keybindings
|
||||||
# --remove-from-cache
|
# --remove-from-cache
|
||||||
|
# --edit-lyrics
|
||||||
|
# --lyrics-custom
|
||||||
case "${1:-}" in
|
case "${1:-}" in
|
||||||
"--lines")
|
"--lines")
|
||||||
# Print lines that are fed into fzf.
|
# Print lines that are fed into fzf.
|
||||||
@@ -198,7 +223,7 @@ case "${1:-}" in
|
|||||||
cnt=$(echo "$j" | $JQ 'length')
|
cnt=$(echo "$j" | $JQ 'length')
|
||||||
[ "$cnt" -eq 1 ] && aid="$(echo "$j" | $JQ '.[0].artist.id')"
|
[ "$cnt" -eq 1 ] && aid="$(echo "$j" | $JQ '.[0].artist.id')"
|
||||||
fi
|
fi
|
||||||
[ "${aid:-}" ] && $0 --action-draw "$mode" "$VIEW_ARTIST" "$aid" || printf "print(%s)+print(%s)+print(%s)+print(%s)+accept" "$VIEW_SELECT_ARTIST" "$j" "$view" "$mbid_cur"
|
[ "${aid:-}" ] && $0 --action-draw "$mode" "$VIEW_ARTIST" "0" "$aid" || printf "print(%s)+print(%s)+print(%s)+print(%s)+accept" "$VIEW_SELECT_ARTIST" "$j" "$view" "$mbid_cur"
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
"--action-draw")
|
"--action-draw")
|
||||||
@@ -206,34 +231,34 @@ case "${1:-}" in
|
|||||||
#
|
#
|
||||||
# @argument $2: mode (default `normal`)
|
# @argument $2: mode (default `normal`)
|
||||||
# @argument $3: view (default list artists)
|
# @argument $3: view (default list artists)
|
||||||
# @argument $4: MusicBrainz ID (optional)
|
# @argument $4: level
|
||||||
# @argument $5: level (optional)
|
# @argument $5: MusicBrainz ID (optional)
|
||||||
#
|
#
|
||||||
# The argument `level` specifies the view relative to `view`: If `level` is
|
# The argument `level` specifies the view relative to `view`: If `level` is
|
||||||
# set to +1, then the specified MusicBrainz ID is an ID of an object one level
|
# set to +1, then the specified MusicBrainz ID is an ID of an object one
|
||||||
# deeper than `view`. Alternatively, the argument `level` may be set to `-1`.
|
# level deeper than `view`. Similarly, the argument `level` may be set to
|
||||||
# Anything else is interpreted as "on the level of `view`".
|
# `-1`. Anything else is interpreted as "on the level of `view`".
|
||||||
#
|
#
|
||||||
# The choice of possible arguments ($5) depends on the view.
|
# The choice of possible levels ($4) depends on the view.
|
||||||
# These views are independent of the MusicBrainz ID ($4) and of the argument
|
# These views are independent of the MusicBrainz ID ($5) and of the argument
|
||||||
# ($5):
|
# ($5):
|
||||||
# - VIEW_SEARCH_ARTIST: Get ready to query MusicBrainz for artists
|
# - VIEW_SEARCH_ARTIST: Get ready to query MusicBrainz for artists
|
||||||
# - VIEW_SEARCH_ALBUM: Get ready to query MusicBrainz for albums
|
# - VIEW_SEARCH_ALBUM: Get ready to query MusicBrainz for albums
|
||||||
# - VIEW_LIST_ARTISTS: List all locally available artists
|
# - VIEW_LIST_ARTISTS: List all locally available artists
|
||||||
# - VIEW_LIST_ALBUMS: List al locally available albums
|
# - VIEW_LIST_ALBUMS: List al locally available albums
|
||||||
#
|
#
|
||||||
# If no argument ($5) is specified, then the remaining views act as follows:
|
# If no level ($4) is specified, then the remaining views act as follows:
|
||||||
# - VIEW_ARTIST: Display all release groups of that artist
|
# - VIEW_ARTIST: Display all release groups of that artist
|
||||||
# - VIEW_RELEASEGROUP: Display all releases within that release group
|
# - VIEW_RELEASEGROUP: Display all releases within that release group
|
||||||
# - VIEW_RELEASE: Display track list of specified release
|
# - VIEW_RELEASE: Display track list of specified release
|
||||||
#
|
#
|
||||||
# Here, if the argument is set to `-1`, then the parent entry is displayed:
|
# Here, if the level is set to `-1`, then the parent entry is displayed:
|
||||||
# - VIEW_ARTIST: Divert view to VIEW_LIST_ARTISTS
|
# - VIEW_ARTIST: Divert view to VIEW_LIST_ARTISTS
|
||||||
# - VIEW_RELEASEGROUP: For single-artist release groups, divert to
|
# - VIEW_RELEASEGROUP: For single-artist release groups, divert to
|
||||||
# VIEW_ARTIST of that artist, else display the artist selection.
|
# VIEW_ARTIST of that artist, else display the artist selection.
|
||||||
# - VIEW_RELEASE: Divert view to VIEW_LIST_RELEASEGROUP.
|
# - VIEW_RELEASE: Divert view to VIEW_LIST_RELEASEGROUP.
|
||||||
#
|
#
|
||||||
# Alternatively, if the argument is set to `+1`, then the child entry is
|
# Alternatively, if the level is set to `+1`, then the child entry is
|
||||||
# displayed:
|
# displayed:
|
||||||
# - VIEW_ARTIST: Divert view to VIEW_LIST_ARTISTS
|
# - VIEW_ARTIST: Divert view to VIEW_LIST_ARTISTS
|
||||||
# - VIEW_RELEASEGROUP: For single-artist release groups, divert to
|
# - VIEW_RELEASEGROUP: For single-artist release groups, divert to
|
||||||
@@ -241,8 +266,8 @@ case "${1:-}" in
|
|||||||
# - VIEW_RELEASE: Divert view to VIEW_LIST_RELEASEGROUP.
|
# - VIEW_RELEASE: Divert view to VIEW_LIST_RELEASEGROUP.
|
||||||
mode="${2:-"$MODE_NORMAL"}"
|
mode="${2:-"$MODE_NORMAL"}"
|
||||||
view="${3:-"$VIEW_LIST_ARTISTS"}"
|
view="${3:-"$VIEW_LIST_ARTISTS"}"
|
||||||
mbid="${4:-}"
|
level="${4:-}"
|
||||||
level="${5:-}"
|
mbid="${5:-}"
|
||||||
# Change state, if we are being diverted.
|
# Change state, if we are being diverted.
|
||||||
case "$level" in
|
case "$level" in
|
||||||
"-1")
|
"-1")
|
||||||
@@ -266,6 +291,7 @@ case "${1:-}" in
|
|||||||
"$VIEW_SEARCH_ARTIST" | "$VIEW_LIST_ARTISTS") view="$VIEW_ARTIST" ;;
|
"$VIEW_SEARCH_ARTIST" | "$VIEW_LIST_ARTISTS") view="$VIEW_ARTIST" ;;
|
||||||
"$VIEW_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ALBUMS") view="$VIEW_RELEASEGROUP" ;;
|
"$VIEW_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ALBUMS") view="$VIEW_RELEASEGROUP" ;;
|
||||||
"$VIEW_RELEASEGROUP") view="$VIEW_RELEASE" ;;
|
"$VIEW_RELEASEGROUP") view="$VIEW_RELEASE" ;;
|
||||||
|
"$VIEW_RELEASE") exit 0 ;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
*) ;;
|
*) ;;
|
||||||
@@ -276,6 +302,7 @@ case "${1:-}" in
|
|||||||
printf "show-input+change-query(%s)" "$q"
|
printf "show-input+change-query(%s)" "$q"
|
||||||
# Store current state
|
# Store current state
|
||||||
printf "+change-list-label(%s)" "$view"
|
printf "+change-list-label(%s)" "$view"
|
||||||
|
printf "+change-border-label(%s)" "$mbid"
|
||||||
# Set header
|
# Set header
|
||||||
fzf_command_set_header "$view" "$mbid"
|
fzf_command_set_header "$view" "$mbid"
|
||||||
# Set preview window
|
# Set preview window
|
||||||
@@ -348,20 +375,22 @@ case "${1:-}" in
|
|||||||
esac
|
esac
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
|
"--edit-lyrics")
|
||||||
|
# Edit lyrics file in an external window
|
||||||
|
info "Call to $*"
|
||||||
|
mbid="${2:-}"
|
||||||
|
file="$(lyrics_file "$mbid")"
|
||||||
|
[ -f "$file" ] || echo "No lyrics" | store_lyrics "$mbid"
|
||||||
|
[ "$EXTERNALEDIT" ] && $EXTERNALEDIT "$file" || err "Failed to externally edit the file $file"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
"--lyrics-custom")
|
||||||
|
# Use custom command to (re-)fetch the lyrics
|
||||||
|
store_lyrics_custom "$2" "$3"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
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
|
||||||
@@ -412,6 +441,22 @@ case "${1:-}" in
|
|||||||
info "Done"
|
info "Done"
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
|
"--playlists")
|
||||||
|
# List available playlists
|
||||||
|
stored_playlists | cut -d "$(printf '\t')" -f 1
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
"--print-playlist")
|
||||||
|
# Pretty print playlist
|
||||||
|
list_playlist_stored "${2:-}" |
|
||||||
|
cut -d "$(printf '\t')" -f 1
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
"--lyrics")
|
||||||
|
shift
|
||||||
|
lyrics "$@"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
"--help")
|
"--help")
|
||||||
# Print help string
|
# Print help string
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
@@ -426,6 +471,10 @@ GENERAL OPTIONS:
|
|||||||
--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>
|
||||||
|
--playlists List stored playlists and exit
|
||||||
|
--load-playlist <playlist> Load specified playlist
|
||||||
|
--print-playlist <playlist> Print specified playlist and exit
|
||||||
|
--lyrics <relid> <mbid> Show lyrics of track <mbid> in release <relid> and exit
|
||||||
|
|
||||||
MANAGE LOCAL MUSIC:
|
MANAGE LOCAL MUSIC:
|
||||||
--decorate <path> Decorate directory containing a tagged release
|
--decorate <path> Decorate directory containing a tagged release
|
||||||
@@ -478,14 +527,23 @@ case "${1:-}" in
|
|||||||
MODE="$MODE_NORMAL"
|
MODE="$MODE_NORMAL"
|
||||||
MBID=""
|
MBID=""
|
||||||
;;
|
;;
|
||||||
|
"--load-playlist")
|
||||||
|
# We will load and play later
|
||||||
|
VIEW="$VIEW_PLAYLIST"
|
||||||
|
MODE="$MODE_NORMAL"
|
||||||
|
MBID=""
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
err "Unknown option $1 (see --help)"
|
err "Unknown option $1 (see --help)"
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
# For history purpose: previous view is always:
|
||||||
|
LASTVIEW="$VIEW_LIST_ARTISTS"
|
||||||
|
LASTARG=""
|
||||||
|
|
||||||
# Start application:
|
# Start application:
|
||||||
# - load and export preset filters
|
|
||||||
# - set title
|
# - set title
|
||||||
# - check for missing data from MusicBrainz
|
# - check for missing data from MusicBrainz
|
||||||
# - precompute main views
|
# - precompute main views
|
||||||
@@ -493,9 +551,6 @@ esac
|
|||||||
# - start mpv daemon
|
# - start mpv daemon
|
||||||
# - enter main loop and start fzf
|
# - enter main loop and start fzf
|
||||||
|
|
||||||
# Load filters
|
|
||||||
. "sh/filter.sh"
|
|
||||||
|
|
||||||
# Set window title
|
# Set window title
|
||||||
printf '\033]0;%s\007' "$WINDOW_TITLE"
|
printf '\033]0;%s\007' "$WINDOW_TITLE"
|
||||||
|
|
||||||
@@ -505,6 +560,9 @@ local_files_present || load_missing_files
|
|||||||
precompute_views
|
precompute_views
|
||||||
|
|
||||||
# Generate filenames for temporary files
|
# Generate filenames for temporary files
|
||||||
|
# We keep these files in a temporary directory and not in the state directory
|
||||||
|
# because this allows for straight-forward capability to run multiple instances
|
||||||
|
# simultaneously.
|
||||||
tmpdir=$(mktemp -d)
|
tmpdir=$(mktemp -d)
|
||||||
LOCKFILE="$tmpdir/lock"
|
LOCKFILE="$tmpdir/lock"
|
||||||
RESULTS="$tmpdir/results"
|
RESULTS="$tmpdir/results"
|
||||||
@@ -515,29 +573,38 @@ export LOCKFILE RESULTS PIDFILE
|
|||||||
# Start mpv
|
# Start mpv
|
||||||
mpv_start
|
mpv_start
|
||||||
|
|
||||||
|
# Playback possible now
|
||||||
|
if [ "${1:-}" = "--load-playlist" ]; then
|
||||||
|
sleep 1
|
||||||
|
$0 --playlist "$PLAYLIST_CMD_LOAD" "${2:-}"
|
||||||
|
fi
|
||||||
|
|
||||||
# main loop
|
# main loop
|
||||||
# states are stored in (in)visible labels
|
# states are stored in (in)visible labels
|
||||||
#
|
#
|
||||||
# mode: [$MODE_NORMAL, $MODE_INSERT]
|
# mode: [$MODE_NORMAL, $MODE_INSERT]
|
||||||
# The mode is reflected on the input visibility. The variable $FZF_INPUT_STATE
|
# The mode is reflected on the input visibility. The variable
|
||||||
# is set to "hidden" if and only if the mode is `normal`. To swtich to `normal`
|
# `FZF_INPUT_STATE`` is set to "hidden" if and only if the mode is `normal`. To
|
||||||
# mode, we call `hide-input`. To switch to insert mode, we call `show-input`.
|
# swtich to `normal` mode, we call `hide-input`. To switch to insert mode, we
|
||||||
|
# call `show-input`.
|
||||||
#
|
#
|
||||||
# view: [$VIEW_*]
|
# view: [$VIEW_*]
|
||||||
# The view is stored in $FZF_LIST_LABEL. To set the view, call
|
# The view is stored in `FZF_LIST_LABEL`. To set the view, call
|
||||||
# `change-list-label($VIEW)`.
|
# `change-list-label($VIEW)`.
|
||||||
#
|
#
|
||||||
# argument: string
|
# mbid:
|
||||||
# The argument is stored in $FZF_LIST_LABEL. To set the argument, call
|
# The MusicBrainz ID of the current object is stored in `FZF_BORDER_LABEL`.
|
||||||
# `change-list-label($arg)`.
|
|
||||||
IN_NORMAL_MODE="[ \$FZF_INPUT_STATE = hidden ]"
|
IN_NORMAL_MODE="[ \$FZF_INPUT_STATE = hidden ]"
|
||||||
IN_VIEW_PATTERN="[ \$FZF_LIST_LABEL = %s ]"
|
IN_VIEW_PATTERN="[ \$FZF_LIST_LABEL = %s ]"
|
||||||
IN_LIST_ARTISTS_VIEW="$(printf "$IN_VIEW_PATTERN" "$VIEW_LIST_ARTISTS")"
|
IN_LIST_ARTISTS_VIEW="$(printf "$IN_VIEW_PATTERN" "$VIEW_LIST_ARTISTS")"
|
||||||
|
IN_RELEASE_VIEW="$(printf "$IN_VIEW_PATTERN" "$VIEW_RELEASE")"
|
||||||
FZF_CURRENT_MODE="\$FZF_INPUT_STATE"
|
FZF_CURRENT_MODE="\$FZF_INPUT_STATE"
|
||||||
FZF_CURRENT_VIEW="\$FZF_LIST_LABEL"
|
FZF_CURRENT_VIEW="\$FZF_LIST_LABEL"
|
||||||
|
FZF_CURRENT_MBID="\$FZF_BORDER_LABEL"
|
||||||
FZF_RELOAD_PLAYLIST="reload-sync($0 --lines $VIEW_PLAYLIST)"
|
FZF_RELOAD_PLAYLIST="reload-sync($0 --lines $VIEW_PLAYLIST)"
|
||||||
FZF_POS_PLAYLIST="transform:$0 --action-playlistcursor"
|
FZF_POS_PLAYLIST="transform:$0 --action-playlistcursor"
|
||||||
PUT_FZF_KEY_LOGIC="case \$FZF_KEY in space) echo \"put( )\";; left) echo backward-char;; right) echo forward-char;; backspace|bspace|bs) echo backward-delete-char;; delete|del) echo delete-char;; *) echo \"put(\$FZF_KEY)\";; esac"
|
PUT_FZF_KEY_LOGIC="case \$FZF_KEY in space) echo \"put( )\";; left) echo backward-char;; right) echo forward-char;; backspace|bspace|bs) echo backward-delete-char;; delete|del) echo delete-char;; *) echo \"put(\$FZF_KEY)\";; esac"
|
||||||
|
FZF_DEFAULT_PREVIEW_WINDOW="right,$PREVIEW_WINDOW_PERCENTAGE%,border-line,nowrap,<50(hidden)"
|
||||||
while true; do
|
while true; do
|
||||||
case "$VIEW" in
|
case "$VIEW" in
|
||||||
"$VIEW_SELECT_ARTIST")
|
"$VIEW_SELECT_ARTIST")
|
||||||
@@ -553,23 +620,26 @@ while true; do
|
|||||||
--bind="$KEYS_LIST_ALBUMS:print($VIEW_LIST_ALBUMS)+accept" \
|
--bind="$KEYS_LIST_ALBUMS:print($VIEW_LIST_ALBUMS)+accept" \
|
||||||
--bind="$KEYS_SEARCH_ARTIST:print($VIEW_SEARCH_ARTIST)+accept" \
|
--bind="$KEYS_SEARCH_ARTIST:print($VIEW_SEARCH_ARTIST)+accept" \
|
||||||
--bind="$KEYS_SEARCH_ALBUM:print($VIEW_SEARCH_ALBUM)+accept" \
|
--bind="$KEYS_SEARCH_ALBUM:print($VIEW_SEARCH_ALBUM)+accept" \
|
||||||
--bind="$KEYS_BROWSE:execute-silent:open \"https://musicbrainz.org/artist/{r3}\"" \
|
--bind="$KEYS_BROWSE:execute-silent:open \"https://musicbrainz.org/artist/{r4}\"" \
|
||||||
--bind="$KEYS_SHOW_PLAYLIST:print($VIEW_PLAYLIST)+print()+accept" \
|
--bind="$KEYS_SHOW_PLAYLIST:print($VIEW_PLAYLIST)+print()+accept" \
|
||||||
--bind="$KEYS_KEYBINDINGS:preview:$0 --show-keybindings $VIEW_SELECT_ARTIST" \
|
--bind="$KEYS_KEYBINDINGS:preview:$0 --show-keybindings $VIEW_SELECT_ARTIST" \
|
||||||
--bind="$KEYS_SCROLL_PREVIEW_DOWN:preview-down" \
|
--bind="$KEYS_SCROLL_PREVIEW_DOWN:preview-down" \
|
||||||
--bind="$KEYS_SCROLL_PREVIEW_UP:preview-up" \
|
--bind="$KEYS_SCROLL_PREVIEW_UP:preview-up" \
|
||||||
|
--bind="$KEYS_PREVIEW_TOGGLE_WRAP:toggle-preview-wrap" \
|
||||||
|
--bind="$KEYS_PREVIEW_TOGGLE_SIZE:change-preview-window(right,90%,border-line,nowrap|$FZF_DEFAULT_PREVIEW_WINDOW)" \
|
||||||
--bind="$KEYS_PREVIEW_OPEN:show-preview" \
|
--bind="$KEYS_PREVIEW_OPEN:show-preview" \
|
||||||
--bind="$KEYS_PREVIEW_CLOSE:hide-preview" \
|
--bind="$KEYS_PREVIEW_CLOSE:hide-preview" \
|
||||||
--bind="$KEYS_FILTER_LOCAL:change-query($QUERY_LOCAL )" \
|
--bind="$KEYS_FILTER_LOCAL:change-query($QUERY_LOCAL )" \
|
||||||
-0 -1 \
|
-0 -1 \
|
||||||
--border="bold" \
|
--border="bold" \
|
||||||
--border-label="Select artist" \
|
--border-label="Select artist" \
|
||||||
--preview-window="right,25%,border-left,wrap,<30(hidden)" \
|
--preview-window="$FZF_DEFAULT_PREVIEW_WINDOW" \
|
||||||
--preview="$0 --preview $VIEW_SELECT_ARTIST {3}" \
|
--wrap-sign="" \
|
||||||
|
--preview="$0 --preview $VIEW_SELECT_ARTIST {4}" \
|
||||||
--delimiter="\t" \
|
--delimiter="\t" \
|
||||||
--prompt="$SEARCH_PROMPT" \
|
--prompt="$SEARCH_PROMPT" \
|
||||||
--margin="5%,20%" \
|
--margin="5%,20%" \
|
||||||
--accept-nth="{3}" \
|
--accept-nth="{4}" \
|
||||||
--with-nth="{1}" || true
|
--with-nth="{1}" || true
|
||||||
)
|
)
|
||||||
lines=$(echo "$sel" | wc -l)
|
lines=$(echo "$sel" | wc -l)
|
||||||
@@ -583,15 +653,80 @@ while true; do
|
|||||||
LASTVIEW="$VIEW_SELECT_ARTIST"
|
LASTVIEW="$VIEW_SELECT_ARTIST"
|
||||||
LASTARG="$ARGS"
|
LASTARG="$ARGS"
|
||||||
;;
|
;;
|
||||||
|
"$VIEW_PLAYLIST_STORE")
|
||||||
|
VIEW="$VIEW_PLAYLIST"
|
||||||
|
ARGS=""
|
||||||
|
MBID=""
|
||||||
|
tmpf=$(mktemp)
|
||||||
|
list_playlist | cut -d "$(printf '\t')" -f "3,4" >"$tmpf"
|
||||||
|
# Make sure we store only nonempty playlists
|
||||||
|
[ -s "$tmpf" ] || continue
|
||||||
|
while true; do
|
||||||
|
infonn "Enter playlist name:"
|
||||||
|
read -r playlistname
|
||||||
|
[ "$playlistname" ] || continue
|
||||||
|
case "$playlistname" in
|
||||||
|
*[!a-zA-Z0-9._-]*)
|
||||||
|
info "Please use only alaphnumeric symbols and any of \".-_\" for the playlist name."
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
f="$PLAYLIST_DIRECTORY/$playlistname"
|
||||||
|
if [ -s "$f" ]; then
|
||||||
|
while true; do
|
||||||
|
infonn "Playlist with name \"$playlistname\" already exists. Do you want to overwrite it? (yes/no)"
|
||||||
|
read -r yn
|
||||||
|
case $yn in
|
||||||
|
"yes" | "no") break ;;
|
||||||
|
*) info "Please answer \"yes\" or \"no\"." ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
[ "$yn" = "yes" ] || continue
|
||||||
|
fi
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
mv "$tmpf" "$f"
|
||||||
|
;;
|
||||||
|
"$VIEW_PLAYLIST_PLAYLISTSTORE")
|
||||||
|
sel=$(
|
||||||
|
stored_playlists | $FZF \
|
||||||
|
--border=double \
|
||||||
|
--border-label="$TITLE_PLYLST_STORE" \
|
||||||
|
--margin="2%,10%" \
|
||||||
|
--bind="$KEYS_I_NORMAL:" \
|
||||||
|
--bind="$KEYS_DOWN:down" \
|
||||||
|
--bind="$KEYS_UP:up" \
|
||||||
|
--bind="$KEYS_HALFPAGE_DOWN:half-page-down" \
|
||||||
|
--bind="$KEYS_HALFPAGE_UP:half-page-up" \
|
||||||
|
--bind="$KEYS_OUT,$KEYS_QUIT:accept" \
|
||||||
|
--bind="$KEYS_KEYBINDINGS:preview:$0 --show-keybindings $VIEW_PLAYLIST_PLAYLISTSTORE" \
|
||||||
|
--bind="$KEYS_SCROLL_PREVIEW_DOWN:preview-down" \
|
||||||
|
--bind="$KEYS_SCROLL_PREVIEW_UP:preview-up" \
|
||||||
|
--bind="$KEYS_PREVIEW_TOGGLE_WRAP:toggle-preview-wrap" \
|
||||||
|
--bind="$KEYS_PREVIEW_TOGGLE_SIZE:change-preview-window(right,90%,border-line,nowrap|$FZF_DEFAULT_PREVIEW_WINDOW)" \
|
||||||
|
--bind="$KEYS_PREVIEW_OPEN:show-preview" \
|
||||||
|
--bind="$KEYS_PREVIEW_CLOSE:hide-preview" \
|
||||||
|
--bind="$KEYS_PLAYLISTSTORE_SELECT:transform:[ {1} ] && $0 --playlist $PLAYLIST_CMD_LOAD {2} && echo accept" \
|
||||||
|
--bind="$KEYS_PLAYLISTSTORE_DELETE:transform:[ {1} ] && rm \"$PLAYLIST_DIRECTORY/{r2}\" && echo \"reload($0 --playlists\)\"" \
|
||||||
|
--preview="$0 --print-playlist {2}" \
|
||||||
|
--preview-window="$FZF_DEFAULT_PREVIEW_WINDOW" \
|
||||||
|
--with-nth="{1}" \
|
||||||
|
--delimiter="\t" \
|
||||||
|
--wrap-sign="" || true
|
||||||
|
)
|
||||||
|
VIEW="$VIEW_PLAYLIST"
|
||||||
|
;;
|
||||||
"$VIEW_PLAYLIST")
|
"$VIEW_PLAYLIST")
|
||||||
sel=$(
|
sel=$(
|
||||||
list_playlist | $FZF \
|
list_playlist | $FZF \
|
||||||
--reverse \
|
--reverse \
|
||||||
--no-sort \
|
--no-sort \
|
||||||
--border=double \
|
--border=double \
|
||||||
--border-label="╢ Playlist ╟" \
|
--border-label="$TITLE_PLYLST" \
|
||||||
--no-input \
|
--no-input \
|
||||||
--margin="2%,10%" \
|
--margin="2%,10%" \
|
||||||
|
--bind="$KEYS_I_NORMAL:" \
|
||||||
--bind="$KEYS_DOWN,$KEYS_N_DOWN:down" \
|
--bind="$KEYS_DOWN,$KEYS_N_DOWN:down" \
|
||||||
--bind="$KEYS_UP,$KEYS_N_UP:up" \
|
--bind="$KEYS_UP,$KEYS_N_UP:up" \
|
||||||
--bind="$KEYS_HALFPAGE_DOWN:half-page-down" \
|
--bind="$KEYS_HALFPAGE_DOWN:half-page-down" \
|
||||||
@@ -599,21 +734,23 @@ while true; do
|
|||||||
--bind="$KEYS_N_BOT:last" \
|
--bind="$KEYS_N_BOT:last" \
|
||||||
--bind="$KEYS_N_TOP:first" \
|
--bind="$KEYS_N_TOP:first" \
|
||||||
--bind="$KEYS_OUT,$KEYS_N_OUT,$KEYS_QUIT,$KEYS_N_QUIT:print($LASTVIEW)+print($LASTARG)+print($VIEW_PLAYLIST)+print()+accept" \
|
--bind="$KEYS_OUT,$KEYS_N_OUT,$KEYS_QUIT,$KEYS_N_QUIT:print($LASTVIEW)+print($LASTARG)+print($VIEW_PLAYLIST)+print()+accept" \
|
||||||
--bind="$KEYS_SELECT_ARTIST:transform:$0 --action-gotoartist $MODE_NORMAL $VIEW_PLAYLIST {2} {3}" \
|
--bind="$KEYS_SELECT_ARTIST:transform:$0 --action-gotoartist $MODE_NORMAL $VIEW_PLAYLIST {3} {4}" \
|
||||||
--bind="$KEYS_LIST_ARTISTS:print($VIEW_LIST_ARTISTS)+accept" \
|
--bind="$KEYS_LIST_ARTISTS:print($VIEW_LIST_ARTISTS)+accept" \
|
||||||
--bind="$KEYS_LIST_ALBUMS:print($VIEW_LIST_ALBUMS)+accept" \
|
--bind="$KEYS_LIST_ALBUMS:print($VIEW_LIST_ALBUMS)+accept" \
|
||||||
--bind="$KEYS_SEARCH_ARTIST:print($VIEW_SEARCH_ARTIST)+accept" \
|
--bind="$KEYS_SEARCH_ARTIST:print($VIEW_SEARCH_ARTIST)+accept" \
|
||||||
--bind="$KEYS_SEARCH_ALBUM:print($VIEW_SEARCH_ALBUM)+accept" \
|
--bind="$KEYS_SEARCH_ALBUM:print($VIEW_SEARCH_ALBUM)+accept" \
|
||||||
--bind="$KEYS_BROWSE:execute-silent:open \"https://musicbrainz.org/\track/{r3}\"" \
|
--bind="$KEYS_BROWSE:execute-silent:open \"https://musicbrainz.org/\track/{r4}\"" \
|
||||||
--bind="$KEYS_OPEN:execute-silent:open \"\$(dirname {4})\"" \
|
--bind="$KEYS_OPEN:execute-silent:open \"\$(dirname {5})\"" \
|
||||||
--bind="$KEYS_N_YANK:execute-silent:printf {3} | $CLIP)" \
|
--bind="$KEYS_N_YANK:execute-silent:printf {4} | $CLIP)" \
|
||||||
--bind="$KEYS_YANK_CURRENT:execute-silent:printf {2} | $CLIP" \
|
--bind="$KEYS_YANK_CURRENT:execute-silent:printf {3} | $CLIP" \
|
||||||
--bind="$KEYS_KEYBINDINGS:preview:$0 --show-keybindings $VIEW_PLAYLIST" \
|
--bind="$KEYS_KEYBINDINGS:preview:$0 --show-keybindings $VIEW_PLAYLIST" \
|
||||||
--bind="$KEYS_SCROLL_PREVIEW_DOWN:preview-down" \
|
--bind="$KEYS_SCROLL_PREVIEW_DOWN:preview-down" \
|
||||||
--bind="$KEYS_SCROLL_PREVIEW_UP:preview-up" \
|
--bind="$KEYS_SCROLL_PREVIEW_UP:preview-up" \
|
||||||
|
--bind="$KEYS_PREVIEW_TOGGLE_WRAP:toggle-preview-wrap" \
|
||||||
|
--bind="$KEYS_PREVIEW_TOGGLE_SIZE:change-preview-window(right,90%,border-line,nowrap|$FZF_DEFAULT_PREVIEW_WINDOW)" \
|
||||||
--bind="$KEYS_PREVIEW_CLOSE:hide-preview" \
|
--bind="$KEYS_PREVIEW_CLOSE:hide-preview" \
|
||||||
--bind="$KEYS_PLAYBACK,$KEYS_N_PLAYBACK:transform($0 --playback $VIEW_PLAYLIST {2} {3} {4})+$FZF_RELOAD_PLAYLIST+$FZF_POS_PLAYLIST" \
|
--bind="$KEYS_PLAYBACK,$KEYS_N_PLAYBACK:transform($0 --playback $VIEW_PLAYLIST {3} {4} {5})+$FZF_RELOAD_PLAYLIST+$FZF_POS_PLAYLIST" \
|
||||||
--bind="$KEYS_PLAYLIST_RELOAD:$FZF_RELOAD_PLAYLIST+$FZF_POS_PLAYLIST" \
|
--bind="$KEYS_PLAYLIST_RELOAD,$KEYS_SHOW_PLAYLIST:$FZF_RELOAD_PLAYLIST+$FZF_POS_PLAYLIST" \
|
||||||
--bind="$KEYS_PLAYLIST_REMOVE:execute-silent($0 --playlist $PLAYLIST_CMD_REMOVE)+$FZF_RELOAD_PLAYLIST" \
|
--bind="$KEYS_PLAYLIST_REMOVE:execute-silent($0 --playlist $PLAYLIST_CMD_REMOVE)+$FZF_RELOAD_PLAYLIST" \
|
||||||
--bind="$KEYS_PLAYLIST_UP:execute-silent($0 --playlist $PLAYLIST_CMD_UP)+up+$FZF_RELOAD_PLAYLIST" \
|
--bind="$KEYS_PLAYLIST_UP:execute-silent($0 --playlist $PLAYLIST_CMD_UP)+up+$FZF_RELOAD_PLAYLIST" \
|
||||||
--bind="$KEYS_PLAYLIST_DOWN:execute-silent($0 --playlist $PLAYLIST_CMD_DOWN)+down+$FZF_RELOAD_PLAYLIST" \
|
--bind="$KEYS_PLAYLIST_DOWN:execute-silent($0 --playlist $PLAYLIST_CMD_DOWN)+down+$FZF_RELOAD_PLAYLIST" \
|
||||||
@@ -623,9 +760,16 @@ while true; do
|
|||||||
--bind="$KEYS_PLAYLIST_SHUFFLE:execute-silent($0 --playlist $PLAYLIST_CMD_SHUFFLE)+$FZF_RELOAD_PLAYLIST" \
|
--bind="$KEYS_PLAYLIST_SHUFFLE:execute-silent($0 --playlist $PLAYLIST_CMD_SHUFFLE)+$FZF_RELOAD_PLAYLIST" \
|
||||||
--bind="$KEYS_PLAYLIST_UNSHUFFLE:execute-silent($0 --playlist $PLAYLIST_CMD_UNSHUFFLE)+$FZF_RELOAD_PLAYLIST" \
|
--bind="$KEYS_PLAYLIST_UNSHUFFLE:execute-silent($0 --playlist $PLAYLIST_CMD_UNSHUFFLE)+$FZF_RELOAD_PLAYLIST" \
|
||||||
--bind="$KEYS_PLAYLIST_GOTO_RELEASE:print($VIEW_RELEASE)+accept" \
|
--bind="$KEYS_PLAYLIST_GOTO_RELEASE:print($VIEW_RELEASE)+accept" \
|
||||||
|
--bind="$KEYS_PLAYLIST_STORE:print($VIEW_PLAYLIST_STORE)+print("")+print($LASTVIEW)+print($LASTARG)+accept" \
|
||||||
|
--bind="$KEYS_PLAYLIST_OPEN_STORE:print($VIEW_PLAYLIST_PLAYLISTSTORE)+print("")+print($LASTVIEW)+print($LASTARG)+accept" \
|
||||||
|
--bind="$KEYS_N_LYRICS:show-preview+preview:$0 --lyrics {3} {4}" \
|
||||||
|
--bind="$KEYS_LYRICS_EDIT:execute-silent:$0 --edit-lyrics {4}" \
|
||||||
|
--bind="$KEYS_N_LYRICS_FETCH_CUSTOM:execute-silent($0 --lyrics-custom {3} {4})+show-preview+preview:$0 --lyrics {3} {4}" \
|
||||||
|
--preview-window="hidden" \
|
||||||
|
--wrap-sign="" \
|
||||||
--delimiter="\t" \
|
--delimiter="\t" \
|
||||||
--with-nth="{1}" \
|
--with-nth="{1}" \
|
||||||
--accept-nth="{2}" || true
|
--accept-nth="{3}" || true
|
||||||
)
|
)
|
||||||
VIEW="$(echo "$sel" | head -1)"
|
VIEW="$(echo "$sel" | head -1)"
|
||||||
ARGS="$(echo "$sel" | head -2 | tail -1)"
|
ARGS="$(echo "$sel" | head -2 | tail -1)"
|
||||||
@@ -656,7 +800,7 @@ while true; do
|
|||||||
--info="inline-right" \
|
--info="inline-right" \
|
||||||
--header-first \
|
--header-first \
|
||||||
--header-border="bottom" \
|
--header-border="bottom" \
|
||||||
--bind="start:transform:$0 --action-draw $MODE $VIEW $MBID" \
|
--bind="start:transform:$0 --action-draw $MODE $VIEW 0 $MBID" \
|
||||||
--bind="$KEYS_I_NORMAL:transform:$IN_NORMAL_MODE || echo hide-input" \
|
--bind="$KEYS_I_NORMAL:transform:$IN_NORMAL_MODE || echo hide-input" \
|
||||||
--bind="$KEYS_N_INSERT:transform:$IN_NORMAL_MODE && echo show-input || $PUT_FZF_KEY_LOGIC" \
|
--bind="$KEYS_N_INSERT:transform:$IN_NORMAL_MODE && echo show-input || $PUT_FZF_KEY_LOGIC" \
|
||||||
--bind="$KEYS_DOWN:down" \
|
--bind="$KEYS_DOWN:down" \
|
||||||
@@ -667,57 +811,62 @@ while true; do
|
|||||||
--bind="$KEYS_N_UP:transform:$IN_NORMAL_MODE && echo up || $PUT_FZF_KEY_LOGIC" \
|
--bind="$KEYS_N_UP:transform:$IN_NORMAL_MODE && echo up || $PUT_FZF_KEY_LOGIC" \
|
||||||
--bind="$KEYS_N_BOT:transform:$IN_NORMAL_MODE && echo last || $PUT_FZF_KEY_LOGIC" \
|
--bind="$KEYS_N_BOT:transform:$IN_NORMAL_MODE && echo last || $PUT_FZF_KEY_LOGIC" \
|
||||||
--bind="$KEYS_N_TOP:transform:$IN_NORMAL_MODE && echo first || $PUT_FZF_KEY_LOGIC" \
|
--bind="$KEYS_N_TOP:transform:$IN_NORMAL_MODE && echo first || $PUT_FZF_KEY_LOGIC" \
|
||||||
--bind="$KEYS_IN:transform:[ {3} ] && $0 --action-draw $FZF_CURRENT_MODE $FZF_CURRENT_VIEW {3} \"+1\"" \
|
--bind="$KEYS_IN:transform:[ {4} ] && $0 --action-draw $FZF_CURRENT_MODE $FZF_CURRENT_VIEW \"+1\" {4}" \
|
||||||
--bind="$KEYS_OUT:transform:[ {2} ] && $0 --action-draw $FZF_CURRENT_MODE $FZF_CURRENT_VIEW {2} \"-1\"" \
|
--bind="$KEYS_OUT:transform:$0 --action-draw $FZF_CURRENT_MODE $FZF_CURRENT_VIEW \"-1\" $FZF_CURRENT_MBID" \
|
||||||
--bind="$KEYS_N_IN:transform:$IN_NORMAL_MODE && ([ {3} ] && $0 --action-draw $FZF_CURRENT_MODE $FZF_CURRENT_VIEW {3} \"+1\") || $PUT_FZF_KEY_LOGIC" \
|
--bind="$KEYS_N_IN:transform:$IN_NORMAL_MODE && ([ {4} ] && $0 --action-draw $FZF_CURRENT_MODE $FZF_CURRENT_VIEW \"+1\" {4}) || $PUT_FZF_KEY_LOGIC" \
|
||||||
--bind="$KEYS_N_OUT:transform:$IN_NORMAL_MODE && ([ {2} ] && $0 --action-draw $FZF_CURRENT_MODE $FZF_CURRENT_VIEW {2} \"-1\") || $PUT_FZF_KEY_LOGIC" \
|
--bind="$KEYS_N_OUT:transform:$IN_NORMAL_MODE && ($0 --action-draw $FZF_CURRENT_MODE $FZF_CURRENT_VIEW \"-1\" $FZF_CURRENT_MBID) || $PUT_FZF_KEY_LOGIC" \
|
||||||
--bind="$KEYS_SELECT_ARTIST:transform:$0 --action-gotoartist $FZF_CURRENT_MODE $FZF_CURRENT_VIEW {2} {3}" \
|
--bind="$KEYS_SELECT_ARTIST:transform:$0 --action-gotoartist $FZF_CURRENT_MODE $FZF_CURRENT_VIEW \"$FZF_CURRENT_MBID\" {4}" \
|
||||||
--bind="$KEYS_LIST_ARTISTS:transform:$0 --action-draw \$FZF_INPUT_STATE $VIEW_LIST_ARTISTS" \
|
--bind="$KEYS_LIST_ARTISTS:transform:$0 --action-draw \$FZF_INPUT_STATE $VIEW_LIST_ARTISTS \"0\"" \
|
||||||
--bind="$KEYS_LIST_ALBUMS:transform:$0 --action-draw \$FZF_INPUT_STATE $VIEW_LIST_ALBUMS" \
|
--bind="$KEYS_LIST_ALBUMS:transform:$0 --action-draw \$FZF_INPUT_STATE $VIEW_LIST_ALBUMS \"0\"" \
|
||||||
--bind="$KEYS_SEARCH_ARTIST:transform:$0 --action-draw $MODE_INSERT $VIEW_SEARCH_ARTIST" \
|
--bind="$KEYS_SEARCH_ARTIST:transform:$0 --action-draw $MODE_INSERT $VIEW_SEARCH_ARTIST \"0\"" \
|
||||||
--bind="$KEYS_SEARCH_ALBUM:transform:$0 --action-draw $MODE_INSERT $VIEW_SEARCH_ALBUM" \
|
--bind="$KEYS_SEARCH_ALBUM:transform:$0 --action-draw $MODE_INSERT $VIEW_SEARCH_ALBUM \"0\"" \
|
||||||
--bind="$KEYS_SWITCH_ARTIST_ALBUM:transform:case $FZF_CURRENT_VIEW in
|
--bind="$KEYS_SWITCH_ARTIST_ALBUM:transform:case $FZF_CURRENT_VIEW in
|
||||||
$VIEW_LIST_ARTISTS) $0 --action-draw $FZF_CURRENT_MODE $VIEW_LIST_ALBUMS ;;
|
$VIEW_LIST_ARTISTS) $0 --action-draw $FZF_CURRENT_MODE $VIEW_LIST_ALBUMS \"0\" ;;
|
||||||
$VIEW_LIST_ALBUMS) $0 --action-draw $FZF_CURRENT_MODE $VIEW_LIST_ARTISTS ;;
|
$VIEW_LIST_ALBUMS) $0 --action-draw $FZF_CURRENT_MODE $VIEW_LIST_ARTISTS \"0\";;
|
||||||
$VIEW_SEARCH_ARTIST) $0 --action-draw $MODE_INSERT $VIEW_SEARCH_ALBUM ;;
|
$VIEW_SEARCH_ARTIST) $0 --action-draw $MODE_INSERT $VIEW_SEARCH_ALBUM \"0\" ;;
|
||||||
$VIEW_SEARCH_ALBUM) $0 --action-draw $MODE_INSERT $VIEW_SEARCH_ARTIST ;;
|
$VIEW_SEARCH_ALBUM) $0 --action-draw $MODE_INSERT $VIEW_SEARCH_ARTIST \"0\" ;;
|
||||||
esac" \
|
esac" \
|
||||||
--bind="$KEYS_SWITCH_LOCAL_REMOTE:transform:case $FZF_CURRENT_VIEW in
|
--bind="$KEYS_SWITCH_LOCAL_REMOTE:transform:case $FZF_CURRENT_VIEW in
|
||||||
$VIEW_LIST_ARTISTS) $0 --action-draw $MODE_INSERT $VIEW_SEARCH_ARTIST ;;
|
$VIEW_LIST_ARTISTS) $0 --action-draw $MODE_INSERT $VIEW_SEARCH_ARTIST \"0\" ;;
|
||||||
$VIEW_LIST_ALBUMS) $0 --action-draw $MODE_INSERT $VIEW_SEARCH_ALBUM ;;
|
$VIEW_LIST_ALBUMS) $0 --action-draw $MODE_INSERT $VIEW_SEARCH_ALBUM \"0\" ;;
|
||||||
$VIEW_SEARCH_ARTIST) $0 --action-draw $MODE_NORMAL $VIEW_LIST_ARTISTS ;;
|
$VIEW_SEARCH_ARTIST) $0 --action-draw $MODE_NORMAL $VIEW_LIST_ARTISTS \"0\" ;;
|
||||||
$VIEW_SEARCH_ALBUM) $0 --action-draw $MODE_NORMAL $VIEW_LIST_ALBUMS ;;
|
$VIEW_SEARCH_ALBUM) $0 --action-draw $MODE_NORMAL $VIEW_LIST_ALBUMS \"0\" ;;
|
||||||
esac" \
|
esac" \
|
||||||
--bind="$KEYS_FILTER:transform:$0 --action-filter $FZF_CURRENT_MODE $FZF_CURRENT_VIEW" \
|
--bind="$KEYS_FILTER:transform:$0 --action-filter $FZF_CURRENT_MODE $FZF_CURRENT_VIEW" \
|
||||||
--bind="$KEYS_BROWSE:execute-silent:
|
--bind="$KEYS_BROWSE:execute-silent:
|
||||||
[ {3} ] || exit 0
|
[ {4} ] || exit 0
|
||||||
case $FZF_CURRENT_VIEW in
|
case $FZF_CURRENT_VIEW in
|
||||||
$VIEW_LIST_ARTISTS | $VIEW_SEARCH_ARTIST) t=artist ;;
|
$VIEW_LIST_ARTISTS | $VIEW_SEARCH_ARTIST) t=artist ;;
|
||||||
$VIEW_ARTIST | $VIEW_SEARCH_ALBUM | $VIEW_LIST_ALBUMS) t=release-group ;;
|
$VIEW_ARTIST | $VIEW_SEARCH_ALBUM | $VIEW_LIST_ALBUMS) t=release-group ;;
|
||||||
$VIEW_RELEASEGROUP) t=release ;;
|
$VIEW_RELEASEGROUP) t=release ;;
|
||||||
$VIEW_RELEASE) t=track ;;
|
$VIEW_RELEASE) t=track ;;
|
||||||
esac
|
esac
|
||||||
open \"https://musicbrainz.org/\$t/{r3}\"" \
|
open \"https://musicbrainz.org/\$t/{r4}\"" \
|
||||||
--bind="$KEYS_OPEN:execute-silent:
|
--bind="$KEYS_OPEN:execute-silent:
|
||||||
[ {4} ] || exit 0
|
[ {5} ] || exit 0
|
||||||
open \"\$(dirname {4})\"" \
|
open \"\$(dirname {5})\"" \
|
||||||
--bind="$KEYS_N_YANK:transform:$IN_NORMAL_MODE && echo \"execute-silent(printf {3} | $CLIP)\" || $PUT_FZF_KEY_LOGIC" \
|
--bind="$KEYS_N_YANK:transform:$IN_NORMAL_MODE && echo \"execute-silent(printf {4} | $CLIP)\" || $PUT_FZF_KEY_LOGIC" \
|
||||||
--bind="$KEYS_YANK_CURRENT:execute-silent:printf {2} | $CLIP" \
|
--bind="$KEYS_YANK_CURRENT:execute-silent:printf $FZF_CURRENT_MBID | $CLIP" \
|
||||||
--bind="$KEYS_SHOW_PLAYLIST:transform:echo \"print($VIEW_PLAYLIST)+print()+print($FZF_CURRENT_VIEW)+print({2})+accept\"" \
|
--bind="$KEYS_SHOW_PLAYLIST:transform:echo \"print($VIEW_PLAYLIST)+print()+print($FZF_CURRENT_VIEW)+print($FZF_CURRENT_MBID)+accept\"" \
|
||||||
--bind="$KEYS_KEYBINDINGS:preview:$0 --show-keybindings $FZF_CURRENT_VIEW" \
|
--bind="$KEYS_KEYBINDINGS:preview:$0 --show-keybindings $FZF_CURRENT_VIEW" \
|
||||||
--bind="$KEYS_REFRESH:execute-silent($0 --remove-from-cache $FZF_CURRENT_VIEW {2} {3})+transform:$0 --action-draw $FZF_CURRENT_MODE $FZF_CURRENT_VIEW {2}" \
|
--bind="$KEYS_REFRESH:execute-silent($0 --remove-from-cache $FZF_CURRENT_VIEW \"$FZF_CURRENT_MBID\" {4})+transform:$0 --action-draw $FZF_CURRENT_MODE $FZF_CURRENT_VIEW \"0\" $FZF_CURRENT_MBID" \
|
||||||
--bind="$KEYS_QUIT:print($VIEW_QUIT)+accept" \
|
--bind="$KEYS_QUIT:print($VIEW_QUIT)+accept" \
|
||||||
--bind="$KEYS_N_QUIT:transform:$IN_NORMAL_MODE && ($IN_LIST_ARTISTS_VIEW && echo \"print($VIEW_QUIT)+accept\" || $0 --action-draw $MODE_NORMAL $VIEW_LIST_ARTISTS) || $PUT_FZF_KEY_LOGIC" \
|
--bind="$KEYS_N_QUIT:transform:$IN_NORMAL_MODE && ($IN_LIST_ARTISTS_VIEW && echo \"print($VIEW_QUIT)+accept\" || $0 --action-draw $MODE_NORMAL $VIEW_LIST_ARTISTS \"0\") || $PUT_FZF_KEY_LOGIC" \
|
||||||
--bind="$KEYS_SCROLL_PREVIEW_DOWN:preview-down" \
|
--bind="$KEYS_SCROLL_PREVIEW_DOWN:preview-down" \
|
||||||
--bind="$KEYS_SCROLL_PREVIEW_UP:preview-up" \
|
--bind="$KEYS_SCROLL_PREVIEW_UP:preview-up" \
|
||||||
|
--bind="$KEYS_PREVIEW_TOGGLE_WRAP:toggle-preview-wrap" \
|
||||||
|
--bind="$KEYS_PREVIEW_TOGGLE_SIZE:change-preview-window(right,90%,border-line,nowrap|$FZF_DEFAULT_PREVIEW_WINDOW)" \
|
||||||
--bind="$KEYS_PREVIEW_OPEN:show-preview" \
|
--bind="$KEYS_PREVIEW_OPEN:show-preview" \
|
||||||
--bind="$KEYS_PREVIEW_CLOSE:hide-preview" \
|
--bind="$KEYS_PREVIEW_CLOSE:hide-preview" \
|
||||||
--bind="$KEYS_PLAYBACK:transform:$0 --playback $FZF_CURRENT_VIEW {2} {3} {4}" \
|
--bind="$KEYS_PLAYBACK:transform:$0 --playback $FZF_CURRENT_VIEW \"$FZF_CURRENT_MBID\" {4} {5}" \
|
||||||
--bind="$KEYS_N_PLAYBACK:transform:$IN_NORMAL_MODE && $0 --playback $FZF_CURRENT_VIEW {2} {3} {4} || $PUT_FZF_KEY_LOGIC" \
|
--bind="$KEYS_N_PLAYBACK:transform:$IN_NORMAL_MODE && $0 --playback $FZF_CURRENT_VIEW \"$FZF_CURRENT_MBID\" {4} {5} || $PUT_FZF_KEY_LOGIC" \
|
||||||
--bind="W:execute-silent:echo 1 >> /tmp/foo; echo $FZF_CURRENT_VIEW >> /tmp/foo; echo 2 >> /tmp/foo" \
|
--bind="$KEYS_N_LYRICS:transform:$IN_NORMAL_MODE && $IN_RELEASE_VIEW && printf \"show-preview+preview:%s --lyrics %s %s\" \"$0\" {3} {4}" \
|
||||||
|
--bind="$KEYS_LYRICS_EDIT:transform:$IN_RELEASE_VIEW && printf \"execute-silent:%s --edit-lyrics %s\" \"$0\" {4}" \
|
||||||
|
--bind="$KEYS_N_LYRICS_FETCH_CUSTOM:transform:$IN_NORMAL_MODE && $IN_RELEASE_VIEW && {$0 --lyrics-custom {3} {4};printf \"show-preview+preview:%s --lyrics %s %s\" \"$0\" {3} {4}}" \
|
||||||
--bind="change:execute-silent($0 --mbsearch $FZF_CURRENT_VIEW &)+reload:$0 --lines $FZF_CURRENT_VIEW" \
|
--bind="change:execute-silent($0 --mbsearch $FZF_CURRENT_VIEW &)+reload:$0 --lines $FZF_CURRENT_VIEW" \
|
||||||
--preview-window="right,25%,border-left,wrap,<30(hidden)" \
|
--preview-window="$FZF_DEFAULT_PREVIEW_WINDOW" \
|
||||||
--preview="$0 --preview $FZF_CURRENT_VIEW {3}" \
|
--wrap-sign="" \
|
||||||
|
--preview="$0 --preview $FZF_CURRENT_VIEW {4}" \
|
||||||
--delimiter="\t" \
|
--delimiter="\t" \
|
||||||
--with-nth="{1}" || true
|
--with-nth="{1}" || true
|
||||||
)
|
)
|
||||||
|
|||||||
337
src/sh/awk.sh
337
src/sh/awk.sh
@@ -1,5 +1,6 @@
|
|||||||
# The code below is used together with `scripts/build.sh`to internalize the awk
|
# The code below is used together with `scripts/build.sh`to internalize the awk
|
||||||
# scripts. See the awk sources for more information.
|
# scripts. See the awk sources for more information.
|
||||||
|
|
||||||
if [ ! "${AWK_LOADED:-}" ]; then
|
if [ ! "${AWK_LOADED:-}" ]; then
|
||||||
AWK_ARTISTS=$(
|
AWK_ARTISTS=$(
|
||||||
cat <<'EOF'
|
cat <<'EOF'
|
||||||
@@ -29,5 +30,341 @@ EOF
|
|||||||
)
|
)
|
||||||
export AWK_RECORDINGS
|
export AWK_RECORDINGS
|
||||||
|
|
||||||
|
AWK_PREVIEW_ARTIST=$(
|
||||||
|
cat <<'EOF'
|
||||||
|
@@include awk/preview_artist.awk
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
export AWK_PREVIEW_ARTIST
|
||||||
|
|
||||||
export AWK_LOADED=1
|
export AWK_LOADED=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Themed awk script to generate list of artists
|
||||||
|
#
|
||||||
|
# @argument $1: Sort specification (may be one of SORT_NO, SORT_NAME,
|
||||||
|
# SORT_SORTNAME)
|
||||||
|
awk_artists() {
|
||||||
|
case "${1:-}" in
|
||||||
|
"$SORT_ARTIST" | "$SORT_ARTIST_SORTNAME") s="$SORT_ALPHA" ;;
|
||||||
|
*) s="$SORT_NO" ;;
|
||||||
|
esac
|
||||||
|
cat |
|
||||||
|
awk \
|
||||||
|
-F "\t" \
|
||||||
|
-v sortby="${1:-}" \
|
||||||
|
-v flagfile="${LOCALDATA_ARTISTS:-}" \
|
||||||
|
-v format="$AV_FMT" \
|
||||||
|
-v flag_local="$AV_FMT_FLAG_LOCAL" \
|
||||||
|
-v flag_nolocal="$AV_FMT_FLAG_NO_LOCAL" \
|
||||||
|
-v type_person="$AV_FMT_TYPE_PERSON" \
|
||||||
|
-v type_group="$AV_FMT_TYPE_GROUP" \
|
||||||
|
-v fmtname="$AV_FMT_NAME" \
|
||||||
|
-v fmtdisambiguation="$AV_FMT_DISAMBIGUATION" \
|
||||||
|
"$AWK_ARTISTS" |
|
||||||
|
column -t -s "$(printf '\t')" -R "$AV_FMT_RIGHTALIGN" -l "$AV_FMT_CNT" |
|
||||||
|
sort_list "$s"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Themed awk script to generate artist header
|
||||||
|
awk_artist_header() {
|
||||||
|
cat |
|
||||||
|
awk \
|
||||||
|
-F "\t" \
|
||||||
|
-v flagfile="${LOCALDATA_ARTISTS:-}" \
|
||||||
|
-v format="$HEADER_ARTIST_FMT" \
|
||||||
|
-v flag_local="$HEADER_ARTIST_FMT_FLAG_LOCAL" \
|
||||||
|
-v flag_nolocal="$HEADER_ARTIST_FMT_FLAG_NO_LOCAL" \
|
||||||
|
-v type_person="$HEADER_ARTIST_FMT_TYPE_PERSON" \
|
||||||
|
-v type_group="$HEADER_ARTIST_FMT_TYPE_GROUP" \
|
||||||
|
-v fmtname="$HEADER_ARTIST_FMT_NAME" \
|
||||||
|
-v fmtdisambiguation="$HEADER_ARTIST_FMT_DISAMBIGUATION" \
|
||||||
|
"$AWK_ARTISTS" |
|
||||||
|
column -t -s "$(printf '\t')" -R "$HEADER_ARTIST_FMT_RIGHTALIGN" -l "$HEADER_ARTIST_FMT_CNT" |
|
||||||
|
cut -d "$(printf '\t')" -f 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Themed awk script to generate list of release groups
|
||||||
|
#
|
||||||
|
# @argument $1: Sort specification (may be one of SORT_NO, SORT_RG_TITLE,
|
||||||
|
# SORT_RG_YEAR)
|
||||||
|
# @argument $2: MusicBrainz artist ID (optional)
|
||||||
|
# @argument $3: Artist credit name (optional)
|
||||||
|
awk_releasegroups() {
|
||||||
|
case "${1:-}" in
|
||||||
|
"$SORT_RG_TITLE") s="$SORT_ALPHA" ;;
|
||||||
|
"$SORT_RG_YEAR") s="$SORT_NUMERIC" ;;
|
||||||
|
*) s="$SORT_NO" ;;
|
||||||
|
esac
|
||||||
|
cat |
|
||||||
|
awk \
|
||||||
|
-F "\t" \
|
||||||
|
-v sortby="${1:-}" \
|
||||||
|
-v artistid="${2:-}" \
|
||||||
|
-v origartist="${3:-}" \
|
||||||
|
-v flagfile="${LOCALDATA_RELEASEGROUPS:-}" \
|
||||||
|
-v format="$RGV_FMT" \
|
||||||
|
-v flag_local="$RGV_FMT_FLAG_LOCAL" \
|
||||||
|
-v flag_nolocal="$RGV_FMT_FLAG_NO_LOCAL" \
|
||||||
|
-v type_single="$RGV_FMT_TYPE_SINGLE" \
|
||||||
|
-v type_album="$RGV_FMT_TYPE_ALBUM" \
|
||||||
|
-v type_ep="$RGV_FMT_TYPE_EP" \
|
||||||
|
-v type_broadcast="$RGV_FMT_TYPE_BROADCAST" \
|
||||||
|
-v type_other="$RGV_FMT_TYPE_OTHER" \
|
||||||
|
-v type_unknown="$RGV_FMT_TYPE_UNKNOWN" \
|
||||||
|
-v hassecondary_yes="$RGV_FMT_HASSECONDARY_YES" \
|
||||||
|
-v hassecondary_no="$RGV_FMT_HASSECONDARY_NO" \
|
||||||
|
-v fmtsecondary="$RGV_FMT_SECONDARY" \
|
||||||
|
-v secondary_compilation="$RGV_FMT_SECONDARY_COMPILATION" \
|
||||||
|
-v secondary_soundtrack="$RGV_FMT_SECONDARY_SOUNDTRACK" \
|
||||||
|
-v secondary_spokenword="$RGV_FMT_SECONDARY_SPOKENWORD" \
|
||||||
|
-v secondary_interview="$RGV_FMT_SECONDARY_INTERVIEW" \
|
||||||
|
-v secondary_audiobook="$RGV_FMT_SECONDARY_AUDIOBOOK" \
|
||||||
|
-v secondary_audiodrama="$RGV_FMT_SECONDARY_AUDIODRAMA" \
|
||||||
|
-v secondary_live="$RGV_FMT_SECONDARY_LIVE" \
|
||||||
|
-v secondary_remix="$RGV_FMT_SECONDARY_REMIX" \
|
||||||
|
-v secondary_djmix="$RGV_FMT_SECONDARY_DJMIX" \
|
||||||
|
-v secondary_mixtape="$RGV_FMT_SECONDARY_MIXTAPE" \
|
||||||
|
-v secondary_demo="$RGV_FMT_SECONDARY_DEMO" \
|
||||||
|
-v secondary_fieldrec="$RGV_FMT_SECONDARY_FIELDREC" \
|
||||||
|
-v fmttitle="$RGV_FMT_TITLE" \
|
||||||
|
-v fmtartist="$RGV_FMT_ARTIST" \
|
||||||
|
-v fmtyear="$RGV_FMT_YEAR" \
|
||||||
|
"$AWK_RELEASEGROUPS" |
|
||||||
|
column -t -s "$(printf '\t')" -R "$RGV_FMT_RIGHTALIGN" -l "$RGV_FMT_CNT" |
|
||||||
|
sort_list "$s"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Themed awk script to generate release-group header
|
||||||
|
awk_releasegroup_header() {
|
||||||
|
cat |
|
||||||
|
awk \
|
||||||
|
-F "\t" \
|
||||||
|
-v flagfile="${LOCALDATA_RELEASEGROUPS:-}" \
|
||||||
|
-v format="$HEADER_RG_FMT" \
|
||||||
|
-v flag_local="$HEADER_RG_FMT_FLAG_LOCAL" \
|
||||||
|
-v flag_nolocal="$HEADER_RG_FMT_FLAG_NO_LOCAL" \
|
||||||
|
-v type_single="$HEADER_RG_FMT_TYPE_SINGLE" \
|
||||||
|
-v type_album="$HEADER_RG_FMT_TYPE_ALBUM" \
|
||||||
|
-v type_ep="$HEADER_RG_FMT_TYPE_EP" \
|
||||||
|
-v type_broadcast="$HEADER_RG_FMT_TYPE_BROADCAST" \
|
||||||
|
-v type_other="$HEADER_RG_FMT_TYPE_OTHER" \
|
||||||
|
-v type_unknown="$HEADER_RG_FMT_TYPE_UNKNOWN" \
|
||||||
|
-v hassecondary_yes="$HEADER_RG_FMT_HASSECONDARY_YES" \
|
||||||
|
-v hassecondary_no="$HEADER_RG_FMT_HASSECONDARY_NO" \
|
||||||
|
-v fmtsecondary="$HEADER_RG_FMT_SECONDARY" \
|
||||||
|
-v secondary_soundtrack="$HEADER_RG_FMT_SECONDARY_SOUNDTRACK" \
|
||||||
|
-v secondary_spokenword="$HEADER_RG_FMT_SECONDARY_SPOKENWORD" \
|
||||||
|
-v secondary_interview="$HEADER_RG_FMT_SECONDARY_INTERVIEW" \
|
||||||
|
-v secondary_audiobook="$HEADER_RG_FMT_SECONDARY_AUDIOBOOK" \
|
||||||
|
-v secondary_audiodrama="$HEADER_RG_FMT_SECONDARY_AUDIODRAMA" \
|
||||||
|
-v secondary_live="$HEADER_RG_FMT_SECONDARY_LIVE" \
|
||||||
|
-v secondary_remix="$HEADER_RG_FMT_SECONDARY_REMIX" \
|
||||||
|
-v secondary_djmix="$HEADER_RG_FMT_SECONDARY_DJMIX" \
|
||||||
|
-v secondary_mixtape="$HEADER_RG_FMT_SECONDARY_MIXTAPE" \
|
||||||
|
-v secondary_demo="$HEADER_RG_FMT_SECONDARY_DEMO" \
|
||||||
|
-v secondary_fieldrec="$HEADER_RG_FMT_SECONDARY_FIELDREC" \
|
||||||
|
-v fmttitle="$HEADER_RG_FMT_TITLE" \
|
||||||
|
-v fmtartist="$HEADER_RG_FMT_ARTIST" \
|
||||||
|
-v fmtyear="$HEADER_RG_FMT_YEAR" \
|
||||||
|
"$AWK_RELEASEGROUPS" |
|
||||||
|
column -t -s "$(printf '\t')" -R "$HEADER_RG_FMT_RIGHTALIGN" -l "$HEADER_RG_FMT_CNT" |
|
||||||
|
cut -d "$(printf '\t')" -f 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Themed awk script to generate list of releases
|
||||||
|
#
|
||||||
|
# @argument $1: MusicBrainz release-group ID (optional)
|
||||||
|
# @argument $2: Title of release group (optional)
|
||||||
|
# @argument $3: Artist credit name of release group
|
||||||
|
awk_releases() {
|
||||||
|
cat |
|
||||||
|
awk \
|
||||||
|
-F "\t" \
|
||||||
|
-v releasegroupid="${1:-}" \
|
||||||
|
-v origtitle="${2:-}" \
|
||||||
|
-v origartist="${3:-}" \
|
||||||
|
-v flagfile="${LOCALDATA_RELEASES:-}" \
|
||||||
|
-v format="$RV_FMT" \
|
||||||
|
-v flag_local="$RV_FMT_FLAG_LOCAL" \
|
||||||
|
-v flag_nolocal="$RV_FMT_FLAG_NO_LOCAL" \
|
||||||
|
-v status_official="$RV_FMT_STATUS_OFFICIAL" \
|
||||||
|
-v status_promo="$RV_FMT_STATUS_PROMO" \
|
||||||
|
-v status_bootleg="$RV_FMT_STATUS_BOOTLEG" \
|
||||||
|
-v status_pseudo="$RV_FMT_STATUS_PSEUDO" \
|
||||||
|
-v status_withdrawn="$RV_FMT_STATUS_WITHDRAWN" \
|
||||||
|
-v status_expunged="$RV_FMT_STATUS_EXPUNGED" \
|
||||||
|
-v status_cancelled="$RV_FMT_STATUS_CANCELLED" \
|
||||||
|
-v status_unknown="$RV_FMT_STATUS_UNKNOWN" \
|
||||||
|
-v fmttracks="$RV_FMT_TRACKS" \
|
||||||
|
-v fmtmedia="$RV_FMT_MEDIA" \
|
||||||
|
-v fmtyear="$RV_FMT_YEAR" \
|
||||||
|
-v fmtcountry="$RV_FMT_COUNTRY" \
|
||||||
|
-v fmtlabel="$RV_FMT_LABEL" \
|
||||||
|
-v fmttitle="$RV_FMT_TITLE" \
|
||||||
|
-v fmtartist="$RV_FMT_ARTIST" \
|
||||||
|
"$AWK_RELEASES" |
|
||||||
|
column -t -s "$(printf '\t')" -R "$RV_FMT_RIGHTALIGN" -l "$RV_FMT_CNT" |
|
||||||
|
sort -t "$(printf '\t')" -k 2,2
|
||||||
|
}
|
||||||
|
|
||||||
|
# Themed awk script to generate release header
|
||||||
|
awk_release_header() {
|
||||||
|
cat |
|
||||||
|
awk \
|
||||||
|
-F "\t" \
|
||||||
|
-v flagfile="${LOCALDATA_RELEASES:-}" \
|
||||||
|
-v format="$HEADER_R_FMT" \
|
||||||
|
-v flag_local="$HEADER_R_FMT_FLAG_LOCAL" \
|
||||||
|
-v flag_nolocal="$HEADER_R_FMT_FLAG_NO_LOCAL" \
|
||||||
|
-v status_official="$HEADER_R_FMT_STATUS_OFFICIAL" \
|
||||||
|
-v status_promo="$HEADER_R_FMT_STATUS_PROMO" \
|
||||||
|
-v status_bootleg="$HEADER_R_FMT_STATUS_BOOTLEG" \
|
||||||
|
-v status_pseudo="$HEADER_R_FMT_STATUS_PSEUDO" \
|
||||||
|
-v status_withdrawn="$HEADER_R_FMT_STATUS_WITHDRAWN" \
|
||||||
|
-v status_expunged="$HEADER_R_FMT_STATUS_EXPUNGED" \
|
||||||
|
-v status_cancelled="$HEADER_R_FMT_STATUS_CANCELLED" \
|
||||||
|
-v status_unknown="$HEADER_R_FMT_STATUS_UNKNOWN" \
|
||||||
|
-v fmttracks="$HEADER_R_FMT_TRACKS" \
|
||||||
|
-v fmtmedia="$HEADER_R_FMT_MEDIA" \
|
||||||
|
-v fmtyear="$HEADER_R_FMT_YEAR" \
|
||||||
|
-v fmtcountry="$HEADER_R_FMT_COUNTRY" \
|
||||||
|
-v fmtlabel="$HEADER_R_FMT_LABEL" \
|
||||||
|
-v fmttitle="$HEADER_R_FMT_TITLE" \
|
||||||
|
-v fmtartist="$HEADER_R_FMT_ARTIST" \
|
||||||
|
"$AWK_RELEASES" |
|
||||||
|
column -t -s "$(printf '\t')" -R "$HEADER_R_FMT_RIGHTALIGN" -l "$HEADER_R_FMT_CNT" |
|
||||||
|
cut -d "$(printf '\t')" -f 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Themed awk script to generate list of tracks
|
||||||
|
#
|
||||||
|
# @argument $1: Path to file with MusicBrainz track IDs "tab" decoration file
|
||||||
|
# of locally playable audio tracks (optional)
|
||||||
|
awk_recordings() {
|
||||||
|
cat |
|
||||||
|
awk \
|
||||||
|
-F "\t" \
|
||||||
|
-v flagfile="${1:-}" \
|
||||||
|
-v format="$REC_FMT" \
|
||||||
|
-v flag_local="$REC_FMT_FLAG_LOCAL" \
|
||||||
|
-v flag_nolocal="$REC_FMT_FLAG_NO_LOCAL" \
|
||||||
|
-v fmtmedia="$REC_FMT_MEDIA" \
|
||||||
|
-v fmtnr="$REC_FMT_NR" \
|
||||||
|
-v fmttitle="$REC_FMT_TITLE" \
|
||||||
|
-v fmtartist="$REC_FMT_ARTIST" \
|
||||||
|
-v fmtduration="$REC_FMT_DURATION" \
|
||||||
|
"$AWK_RECORDINGS" |
|
||||||
|
column -t -s "$(printf '\t')" -R "$REC_FMT_RIGHTALIGN" -l "$REC_FMT_CNT"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Themed awk script to generate list of tracks for playlist view
|
||||||
|
awk_playlist() {
|
||||||
|
cat |
|
||||||
|
awk \
|
||||||
|
-F "\t" \
|
||||||
|
-v format="$PLYLST_FMT" \
|
||||||
|
-v playing_yes="$PLYLST_FMT_PLAYING_YES" \
|
||||||
|
-v playing_no="$PLYLST_FMT_PLAYING_NO" \
|
||||||
|
-v fmttitle="$PLYLST_FMT_TITLE" \
|
||||||
|
-v fmtartist="$PLYLST_FMT_ARTIST" \
|
||||||
|
-v fmtduration="$PLYLST_FMT_DURATION" \
|
||||||
|
"$AWK_RECORDINGS" |
|
||||||
|
column -t -s "$(printf '\t')" -R "$PLYLST_FMT_RIGHTALIGN" -l "$PLYLST_FMT_CNT"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Themed awk scrtip to preview single-person artist
|
||||||
|
#
|
||||||
|
# @argument $1: Artist name
|
||||||
|
# @argument $2: Artist sort name
|
||||||
|
# @argument $3: Artist disambiguation
|
||||||
|
# @argument $4: Artist biography
|
||||||
|
# @argument $5: Artist aliases
|
||||||
|
# @argument $6: Birthdate
|
||||||
|
# @argument $7: Birth place
|
||||||
|
# @argument $8: Date when died
|
||||||
|
# @argument $9: Place where died
|
||||||
|
# @argument $10: Artist urls
|
||||||
|
awk_preview_artist_person() {
|
||||||
|
awk \
|
||||||
|
-v name="${1:-}" \
|
||||||
|
-v sortname="${2:-}" \
|
||||||
|
-v disamb="${3:-}" \
|
||||||
|
-v bio="${4:-}" \
|
||||||
|
-v alias="${5:-}" \
|
||||||
|
-v startdate="${6:-}" \
|
||||||
|
-v startplace="${7:-}" \
|
||||||
|
-v enddate="${8:-}" \
|
||||||
|
-v endplace="${9:-}" \
|
||||||
|
-v url="${10:-}" \
|
||||||
|
-v format="$PREVIEW_ARTIST_PERSON_FMT" \
|
||||||
|
-v fmtname="$PREVIEW_ARTIST_PERSON_NAME" \
|
||||||
|
-v fmtsortname="$PREVIEW_ARTIST_PERSON_SORTNAME" \
|
||||||
|
-v fmtbio="$PREVIEW_ARTIST_PERSON_BIO" \
|
||||||
|
-v fmtdisamb="$PREVIEW_ARTIST_PERSON_DISAMB" \
|
||||||
|
-v fmtalias="$PREVIEW_ARTIST_PERSON_ALIAS" \
|
||||||
|
-v join_alias="$PREVIEW_ARTIST_PERSON_ALIAS_JOIN" \
|
||||||
|
-v format_start="$PREVIEW_ARTIST_PERSON_START_FMT" \
|
||||||
|
-v fmtstart="$PREVIEW_ARTIST_PERSON_START" \
|
||||||
|
-v fmtstart_startdate="$PREVIEW_ARTIST_PERSON_START_STARTDATE" \
|
||||||
|
-v fmtstart_startplace="$PREVIEW_ARTIST_PERSON_START_STARTPLACE" \
|
||||||
|
-v format_end="$PREVIEW_ARTIST_PERSON_END_FMT" \
|
||||||
|
-v fmtend="$PREVIEW_ARTIST_PERSON_END" \
|
||||||
|
-v fmtend_enddate="$PREVIEW_ARTIST_PERSON_END_ENDDATE" \
|
||||||
|
-v fmtend_endplace="$PREVIEW_ARTIST_PERSON_END_ENDPLACE" \
|
||||||
|
-v fmturl="$PREVIEW_ARTIST_PERSON_URL" \
|
||||||
|
-v format_url="$PREVIEW_ARTIST_PERSON_URL_FMT" \
|
||||||
|
-v join_url="$PREVIEW_ARTIST_PERSON_URL_JOIN" \
|
||||||
|
-v fmturl_urlindex="$PREVIEW_ARTIST_PERSON_URL_URLINDEX" \
|
||||||
|
-v fmturl_urlname="$PREVIEW_ARTIST_PERSON_URL_URLNAME" \
|
||||||
|
-v fmturl_urllink="$PREVIEW_ARTIST_PERSON_URL_URLLINK" \
|
||||||
|
"$AWK_PREVIEW_ARTIST"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Themed awk scrtip to preview artist group
|
||||||
|
#
|
||||||
|
# @argument $1: Artist name
|
||||||
|
# @argument $2: Artist sort name
|
||||||
|
# @argument $3: Artist disambiguation
|
||||||
|
# @argument $4: Artist biography
|
||||||
|
# @argument $5: Artist aliases
|
||||||
|
# @argument $6: Founding date
|
||||||
|
# @argument $7: Founding place
|
||||||
|
# @argument $8: Date when dissolved
|
||||||
|
# @argument $9: Place where dissovled
|
||||||
|
# @argument $10: Artist urls
|
||||||
|
awk_preview_artist_group() {
|
||||||
|
awk \
|
||||||
|
-v name="${1:-}" \
|
||||||
|
-v sortname="${2:-}" \
|
||||||
|
-v disamb="${3:-}" \
|
||||||
|
-v bio="${4:-}" \
|
||||||
|
-v alias="${5:-}" \
|
||||||
|
-v startdate="${6:-}" \
|
||||||
|
-v startplace="${7:-}" \
|
||||||
|
-v enddate="${8:-}" \
|
||||||
|
-v endplace="${9:-}" \
|
||||||
|
-v url="${10:-}" \
|
||||||
|
-v format="$PREVIEW_ARTIST_GROUP_FMT" \
|
||||||
|
-v fmtname="$PREVIEW_ARTIST_GROUP_NAME" \
|
||||||
|
-v fmtsortname="$PREVIEW_ARTIST_GROUP_SORTNAME" \
|
||||||
|
-v fmtbio="$PREVIEW_ARTIST_GROUP_BIO" \
|
||||||
|
-v fmtdisamb="$PREVIEW_ARTIST_GROUP_DISAMB" \
|
||||||
|
-v fmtalias="$PREVIEW_ARTIST_GROUP_ALIAS" \
|
||||||
|
-v join_alias="$PREVIEW_ARTIST_GROUP_ALIAS_JOIN" \
|
||||||
|
-v format_start="$PREVIEW_ARTIST_GROUP_START_FMT" \
|
||||||
|
-v fmtstart="$PREVIEW_ARTIST_GROUP_START" \
|
||||||
|
-v fmtstart_startdate="$PREVIEW_ARTIST_GROUP_START_STARTDATE" \
|
||||||
|
-v fmtstart_startplace="$PREVIEW_ARTIST_GROUP_START_STARTPLACE" \
|
||||||
|
-v format_end="$PREVIEW_ARTIST_GROUP_END_FMT" \
|
||||||
|
-v fmtend="$PREVIEW_ARTIST_GROUP_END" \
|
||||||
|
-v fmtend_enddate="$PREVIEW_ARTIST_GROUP_END_ENDDATE" \
|
||||||
|
-v fmtend_endplace="$PREVIEW_ARTIST_GROUP_END_ENDPLACE" \
|
||||||
|
-v fmturl="$PREVIEW_ARTIST_GROUP_URL" \
|
||||||
|
-v format_url="$PREVIEW_ARTIST_GROUP_URL_FMT" \
|
||||||
|
-v join_url="$PREVIEW_ARTIST_GROUP_URL_JOIN" \
|
||||||
|
-v fmturl_urlindex="$PREVIEW_ARTIST_GROUP_URL_URLINDEX" \
|
||||||
|
-v fmturl_urlname="$PREVIEW_ARTIST_GROUP_URL_URLNAME" \
|
||||||
|
-v fmturl_urllink="$PREVIEW_ARTIST_GROUP_URL_URLLINK" \
|
||||||
|
"$AWK_PREVIEW_ARTIST"
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
if [ ! "${CACHE_LOADED:-}" ]; then
|
if [ ! "${CACHE_LOADED:-}" ]; then
|
||||||
# Base path for cache
|
# Base path for cache
|
||||||
CACHEDIR="$HOME/.cache/$APP_NAME"
|
CACHEDIR="${XGD_CACHE_HOME:-"$HOME/.cache"}/$APP_NAME"
|
||||||
# Directory names for cache types
|
# Directory names for cache types
|
||||||
TYPE_ARTIST="artist"
|
TYPE_ARTIST="artist"
|
||||||
TYPE_RELEASEGROUP="releasegroup"
|
TYPE_RELEASEGROUP="releasegroup"
|
||||||
@@ -42,14 +42,14 @@ fi
|
|||||||
#
|
#
|
||||||
# @argument $1: some string
|
# @argument $1: some string
|
||||||
__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"/"$0 }'
|
||||||
}
|
}
|
||||||
|
|
||||||
# Radix transform strings (batch)
|
# Radix transform strings (batch)
|
||||||
#
|
#
|
||||||
# Here, the input is read line-by-line from stdin.
|
# Here, the input is read line-by-line from stdin.
|
||||||
__radix_batch() {
|
__radix_batch() {
|
||||||
cat | awk -F "" '{ print $1$2$3$4"/"$5$6$7$8"/"$0 }'
|
cat | awk -F "" '{ print $1$2"/"$3$4"/"$0 }'
|
||||||
}
|
}
|
||||||
|
|
||||||
# Super wrapper to print json data from cache
|
# Super wrapper to print json data from cache
|
||||||
@@ -238,6 +238,18 @@ cache_get_file_batch() {
|
|||||||
awk -v dir="$CACHEDIR/$1/" -v f="/$fn" '{ print dir $0 f }'
|
awk -v dir="$CACHEDIR/$1/" -v f="/$fn" '{ print dir $0 f }'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Detect missing cache files
|
||||||
|
#
|
||||||
|
# @argument $1: type
|
||||||
|
# @argument $2: path to list with MusicBrainz IDs
|
||||||
|
#
|
||||||
|
# This method returns a nonzero value if some MusicBrainz objects listed in $2
|
||||||
|
# are not cached.
|
||||||
|
cached() {
|
||||||
|
cache_get_file_batch "$1" <"$2" |
|
||||||
|
xargs -d '\n' ls >/dev/null 2>&1 || return 1
|
||||||
|
}
|
||||||
|
|
||||||
# Print MusicBrainz ID associated to the file paths
|
# Print MusicBrainz ID associated to the file paths
|
||||||
#
|
#
|
||||||
# This reads from stdin any number of paths (one per line)
|
# This reads from stdin any number of paths (one per line)
|
||||||
@@ -258,7 +270,7 @@ cache_rm_artist() {
|
|||||||
d="$CACHEDIR/$TYPE_ARTIST/$(__radix "$1")/"
|
d="$CACHEDIR/$TYPE_ARTIST/$(__radix "$1")/"
|
||||||
[ "$d" ] || return 1
|
[ "$d" ] || return 1
|
||||||
[ -d "$d" ] || return 1
|
[ -d "$d" ] || return 1
|
||||||
info "removing $d"
|
info "Removing $d from cache"
|
||||||
rm -rf "$d"
|
rm -rf "$d"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,7 +287,7 @@ cache_rm_releasegroup() {
|
|||||||
d="$CACHEDIR/$TYPE_RELEASEGROUP/$(__radix "$1")/"
|
d="$CACHEDIR/$TYPE_RELEASEGROUP/$(__radix "$1")/"
|
||||||
[ "$d" ] || return 1
|
[ "$d" ] || return 1
|
||||||
[ -d "$d" ] || return 1
|
[ -d "$d" ] || return 1
|
||||||
info "removing $d"
|
info "Removing $d from cache"
|
||||||
rm -rf "$d"
|
rm -rf "$d"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,6 +304,44 @@ cache_rm_release() {
|
|||||||
d="$CACHEDIR/$TYPE_RELEASE/$(__radix "$1")/"
|
d="$CACHEDIR/$TYPE_RELEASE/$(__radix "$1")/"
|
||||||
[ "$d" ] || return 1
|
[ "$d" ] || return 1
|
||||||
[ -d "$d" ] || return 1
|
[ -d "$d" ] || return 1
|
||||||
info "removing $d"
|
info "Removing $d from cache"
|
||||||
rm -rf "$d"
|
rm -rf "$d"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Load missing cache entries (batch mode)
|
||||||
|
#
|
||||||
|
# argument $1: type
|
||||||
|
#
|
||||||
|
# This method reads one MusicBrainz IDs of the specified type from stdin (one
|
||||||
|
# per line), and fetches the missing items.
|
||||||
|
batch_load_missing() {
|
||||||
|
tmpf=$(mktemp)
|
||||||
|
cat |
|
||||||
|
cache_get_file_batch "$1" |
|
||||||
|
xargs -d '\n' \
|
||||||
|
sh -c 'for f; do [ -e "$f" ] || echo "$f"; done' _ |
|
||||||
|
cache_mbid_from_path_batch >"$tmpf"
|
||||||
|
lines=$(wc -l "$tmpf" | cut -d ' ' -f 1)
|
||||||
|
if [ "$lines" -gt 0 ]; then
|
||||||
|
case "$1" in
|
||||||
|
"$TYPE_ARTIST") tt="artists" ;;
|
||||||
|
"$TYPE_RELEASEGROUP") tt="release groups" ;;
|
||||||
|
"$TYPE_RELEASE") tt="releases" ;;
|
||||||
|
esac
|
||||||
|
info "Fetching missing $tt"
|
||||||
|
cnt=0
|
||||||
|
while IFS= read -r mbid; do
|
||||||
|
case "$1" in
|
||||||
|
"$TYPE_ARTIST")
|
||||||
|
name=$(mb_artist "$mbid" | $JQ '.name')
|
||||||
|
;;
|
||||||
|
"$TYPE_RELEASEGROUP") name=$(mb_releasegroup "$mbid" | $JQ '.title') ;;
|
||||||
|
"$TYPE_RELEASE") name=$(mb_release "$mbid" | $JQ '.title') ;;
|
||||||
|
esac
|
||||||
|
cnt=$((cnt + 1))
|
||||||
|
info "$(printf "%d/%d (%s: %s)" "$cnt" "$lines" "$mbid" "$name")"
|
||||||
|
sleep 1
|
||||||
|
done <"$tmpf"
|
||||||
|
fi
|
||||||
|
rm -f "$tmpf"
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,14 +4,15 @@
|
|||||||
# the file may be overwritten by specifying the environment variable
|
# the file may be overwritten by specifying the environment variable
|
||||||
# `CONFIGFILE`. If a configuration file is specified, then it must also exist.
|
# `CONFIGFILE`. If a configuration file is specified, then it must also exist.
|
||||||
# A configuration file comprises the specification of environment variables
|
# A configuration file comprises the specification of environment variables
|
||||||
# that are` allowed to be set.
|
# that are allowed to be set.
|
||||||
#
|
#
|
||||||
# Currently, the following files hold variables that are configurable:
|
# Currently, the following files hold variables that are configurable:
|
||||||
# - `src/sh/filter.sh`: Configuration of filters that can be triggered with
|
# - `src/sh/filter.sh`: Configuration of filters that can be triggered with
|
||||||
# the respective key bindings.
|
# the respective key bindings.
|
||||||
# - `src/sh/keys.sh`: Configuration of key bindings to certain actions
|
# - `src/sh/keys.sh`: Configuration of key bindings to certain actions
|
||||||
# - `src/sh/theme.sh`: Configuration of theme
|
# - `src/sh/theme.sh`: Configuration of theme
|
||||||
CONFIGFILE_DEFAULT="$HOME/.config/$APP_NAME/config"
|
# - `src/sh/sort.sh`: List sorting
|
||||||
|
CONFIGFILE_DEFAULT="${XDG_CONFIG_HOME:-"$HOME/.config"}/$APP_NAME/config"
|
||||||
CONFIGFILE="${CONFIGFILE:-"$CONFIGFILE_DEFAULT"}"
|
CONFIGFILE="${CONFIGFILE:-"$CONFIGFILE_DEFAULT"}"
|
||||||
[ "$CONFIGFILE" != "$CONFIGFILE_DEFAULT" ] && [ ! -f "$CONFIGFILE" ] && err "The configuration file manually specified with the environment variable CONFIGFILE=($CONFIGFILE) does not exist." && exit 1
|
[ "$CONFIGFILE" != "$CONFIGFILE_DEFAULT" ] && [ ! -f "$CONFIGFILE" ] && err "The configuration file manually specified with the environment variable CONFIGFILE=($CONFIGFILE) does not exist." && exit 1
|
||||||
# shellcheck source=/dev/null
|
# shellcheck source=/dev/null
|
||||||
|
|||||||
166
src/sh/filter.sh
166
src/sh/filter.sh
@@ -1,87 +1,91 @@
|
|||||||
# Preset filters for different views. These filters are associated to key
|
# Preset filters for different views. These filters are associated to key
|
||||||
# bindings (see `src/sh/keys.sh`), and are configurable through a configuration
|
# bindings (see `src/sh/keys.sh`), and are configurable through a configuration
|
||||||
# file (see `src/sh/config.sh`).
|
# file (see `src/sh/config.sh`).
|
||||||
|
if [ ! "${FILTER_LOADED:-}" ]; then
|
||||||
|
# The `QUERY_LOCAL` filter is associated with the keys `KEYS_FILTER_LOCAL`.
|
||||||
|
# It is used to hide all entries that are not available locally (see
|
||||||
|
# `src/sh/query.sh` for details and the relevant methods)
|
||||||
|
QUERY_LOCAL="${QUERY_LOCAL:-"$(printf "'%s'" "$FORMAT_LOCAL" | __clean_filter)"}"
|
||||||
|
|
||||||
# The `QUERY_LOCAL` filter is associated with the keys `KEYS_FILTER_LOCAL`. It
|
# The following variables store preset strings derived from the theme (see
|
||||||
# is used to hide all entries that are not available locally (see
|
# `src/sh/theme.sh`), and used in the assignment of the default filters.
|
||||||
# `src/sh/query.sh` for details and the relevant methods)
|
q_has_seconary="$(printf "%s" "$RGV_FMT_HASSECONDARY_YES" | __clean_filter)"
|
||||||
QUERY_LOCAL="${QUERY_LOCAL:-"$(printf "'%s'" "$FORMAT_LOCAL" | __clean_filter)"}"
|
q_album="$(printf "%s" "$RGV_FMT_TYPE_ALBUM" | __clean_filter)"
|
||||||
|
q_ep="$(printf "%s" "$RGV_FMT_TYPE_EP" | __clean_filter)"
|
||||||
|
q_single="$(printf "%s" "$RGV_FMT_TYPE_SINGLE" | __clean_filter)"
|
||||||
|
if printf "$RV_FMT" | grep -q "<<status>>"; then
|
||||||
|
q_official="$(printf "'%s'" "$RV_FMT_STATUS_OFFICIAL" | __clean_filter)"
|
||||||
|
fi
|
||||||
|
export QUERY_LOCAL
|
||||||
|
|
||||||
# The following variables store preset strings derived from the theme (see
|
# Here starts the list of all filters (grouped per view) that are associated
|
||||||
# `src/sh/theme.sh`), and used in the assignment of the default filters.
|
# to the keys `KEYS_FILTER_0` - `KEYS_FILTER_9`. The filters in the
|
||||||
q_has_seconary="$(printf "$FORMAT_TYPE_HAS_SECONDARY" "" | __clean_filter)"
|
# `F_1_<view>` variable are automatically applied whenever the given view is
|
||||||
q_album="$(printf "%s" "$FORMAT_TYPE_ALBUM" | __clean_filter)"
|
# entered.
|
||||||
q_ep=$(printf "%s" "$FORMAT_TYPE_EP" | sed "s/${ESC}\[[0-9;]*[mK]//g" | sed "s/ /\\\ /g")
|
F_1_VIEW_ARTIST="${F_1_VIEW_ARTIST:-"!'$q_has_seconary'"}"
|
||||||
q_single=$(printf "%s" "$FORMAT_TYPE_SINGLE" | sed "s/${ESC}\[[0-9;]*[mK]//g" | sed "s/ /\\\ /g")
|
F_2_VIEW_ARTIST="${F_2_VIEW_ARTIST:-"'$q_album'"}"
|
||||||
if printf "$RV_FORMAT" | grep -q "<<status>>"; then
|
F_3_VIEW_ARTIST="${F_3_VIEW_ARTIST:-"'$q_ep'"}"
|
||||||
q_official=$(printf "'%s'" "$FORMAT_STATUS_OFFICIAL" | sed "s/${ESC}\[[0-9;]*[mK]//g" | sed "s/ /\\\ /g")
|
F_4_VIEW_ARTIST="${F_4_VIEW_ARTIST:-"'$q_single'"}"
|
||||||
|
F_5_VIEW_ARTIST="${F_5_VIEW_ARTIST:-}"
|
||||||
|
F_6_VIEW_ARTIST="${F_6_VIEW_ARTIST:-}"
|
||||||
|
F_7_VIEW_ARTIST="${F_7_VIEW_ARTIST:-}"
|
||||||
|
F_8_VIEW_ARTIST="${F_8_VIEW_ARTIST:-}"
|
||||||
|
F_9_VIEW_ARTIST="${F_9_VIEW_ARTIST:-}"
|
||||||
|
export F_1_VIEW_ARTIST F_2_VIEW_ARTIST F_3_VIEW_ARTIST F_4_VIEW_ARTIST \
|
||||||
|
F_5_VIEW_ARTIST F_6_VIEW_ARTIST F_7_VIEW_ARTIST F_8_VIEW_ARTIST \
|
||||||
|
F_9_VIEW_ARTIST
|
||||||
|
|
||||||
|
F_1_VIEW_RELEASEGROUP="${F_1_VIEW_RELEASEGROUP:-"${q_official:-}"}"
|
||||||
|
F_2_VIEW_RELEASEGROUP="${F_2_VIEW_RELEASEGROUP:-}"
|
||||||
|
F_3_VIEW_RELEASEGROUP="${F_3_VIEW_RELEASEGROUP:-}"
|
||||||
|
F_4_VIEW_RELEASEGROUP="${F_4_VIEW_RELEASEGROUP:-}"
|
||||||
|
F_5_VIEW_RELEASEGROUP="${F_5_VIEW_RELEASEGROUP:-}"
|
||||||
|
F_6_VIEW_RELEASEGROUP="${F_6_VIEW_RELEASEGROUP:-}"
|
||||||
|
F_7_VIEW_RELEASEGROUP="${F_7_VIEW_RELEASEGROUP:-}"
|
||||||
|
F_8_VIEW_RELEASEGROUP="${F_8_VIEW_RELEASEGROUP:-}"
|
||||||
|
F_9_VIEW_RELEASEGROUP="${F_9_VIEW_RELEASEGROUP:-}"
|
||||||
|
export F_1_VIEW_RELEASEGROUP F_2_VIEW_RELEASEGROUP F_3_VIEW_RELEASEGROUP \
|
||||||
|
F_4_VIEW_RELEASEGROUP F_5_VIEW_RELEASEGROUP F_6_VIEW_RELEASEGROUP \
|
||||||
|
F_7_VIEW_RELEASEGROUP F_8_VIEW_RELEASEGROUP F_9_VIEW_RELEASEGROUP
|
||||||
|
|
||||||
|
F_1_VIEW_RELEASE="${F_1_VIEW_RELEASE:-}"
|
||||||
|
F_2_VIEW_RELEASE="${F_2_VIEW_RELEASE:-}"
|
||||||
|
F_3_VIEW_RELEASE="${F_3_VIEW_RELEASE:-}"
|
||||||
|
F_4_VIEW_RELEASE="${F_4_VIEW_RELEASE:-}"
|
||||||
|
F_5_VIEW_RELEASE="${F_5_VIEW_RELEASE:-}"
|
||||||
|
F_6_VIEW_RELEASE="${F_6_VIEW_RELEASE:-}"
|
||||||
|
F_7_VIEW_RELEASE="${F_7_VIEW_RELEASE:-}"
|
||||||
|
F_8_VIEW_RELEASE="${F_8_VIEW_RELEASE:-}"
|
||||||
|
F_9_VIEW_RELEASE="${F_9_VIEW_RELEASE:-}"
|
||||||
|
export F_1_VIEW_RELEASE F_2_VIEW_RELEASE F_3_VIEW_RELEASE F_4_VIEW_RELEASE \
|
||||||
|
F_5_VIEW_RELEASE F_6_VIEW_RELEASE F_7_VIEW_RELEASE F_8_VIEW_RELEASE \
|
||||||
|
F_9_VIEW_RELEASE
|
||||||
|
|
||||||
|
F_1_LIST_ARTISTS="${F_1_LIST_ARTISTS:-}"
|
||||||
|
F_2_LIST_ARTISTS="${F_2_LIST_ARTISTS:-}"
|
||||||
|
F_3_LIST_ARTISTS="${F_3_LIST_ARTISTS:-}"
|
||||||
|
F_4_LIST_ARTISTS="${F_4_LIST_ARTISTS:-}"
|
||||||
|
F_5_LIST_ARTISTS="${F_5_LIST_ARTISTS:-}"
|
||||||
|
F_6_LIST_ARTISTS="${F_6_LIST_ARTISTS:-}"
|
||||||
|
F_7_LIST_ARTISTS="${F_7_LIST_ARTISTS:-}"
|
||||||
|
F_8_LIST_ARTISTS="${F_8_LIST_ARTISTS:-}"
|
||||||
|
F_9_LIST_ARTISTS="${F_9_LIST_ARTISTS:-}"
|
||||||
|
export F_1_LIST_ARTISTS F_2_LIST_ARTISTS F_3_LIST_ARTISTS F_4_LIST_ARTISTS \
|
||||||
|
F_5_LIST_ARTISTS F_6_LIST_ARTISTS F_7_LIST_ARTISTS F_8_LIST_ARTISTS \
|
||||||
|
F_9_LIST_ARTISTS
|
||||||
|
|
||||||
|
F_1_LIST_ALBUMS="${F_1_LIST_ALBUMS:-}"
|
||||||
|
F_2_LIST_ALBUMS="${F_2_LIST_ALBUMS:-}"
|
||||||
|
F_3_LIST_ALBUMS="${F_3_LIST_ALBUMS:-}"
|
||||||
|
F_4_LIST_ALBUMS="${F_4_LIST_ALBUMS:-}"
|
||||||
|
F_5_LIST_ALBUMS="${F_5_LIST_ALBUMS:-}"
|
||||||
|
F_6_LIST_ALBUMS="${F_6_LIST_ALBUMS:-}"
|
||||||
|
F_7_LIST_ALBUMS="${F_7_LIST_ALBUMS:-}"
|
||||||
|
F_8_LIST_ALBUMS="${F_8_LIST_ALBUMS:-}"
|
||||||
|
F_9_LIST_ALBUMS="${F_9_LIST_ALBUMS:-}"
|
||||||
|
export F_1_LIST_ALBUMS F_2_LIST_ALBUMS F_3_LIST_ALBUMS F_4_LIST_ALBUMS \
|
||||||
|
F_5_LIST_ALBUMS F_6_LIST_ALBUMS F_7_LIST_ALBUMS F_8_LIST_ALBUMS \
|
||||||
|
F_9_LIST_ALBUMS
|
||||||
|
|
||||||
|
export FILTER_LOADED=1
|
||||||
fi
|
fi
|
||||||
export QUERY_LOCAL
|
|
||||||
|
|
||||||
# Here starts the list of all filters (grouped per view) that are associated to
|
|
||||||
# the keys `KEYS_FILTER_0` - `KEYS_FILTER_9`. The filters in the `F_1_<view>`
|
|
||||||
# variable are automatically applied whenever the given view is entered.
|
|
||||||
F_1_VIEW_ARTIST="${F_1_VIEW_ARTIST:-"!'$q_has_seconary'"}"
|
|
||||||
F_2_VIEW_ARTIST="${F_2_VIEW_ARTIST:-"'$q_album'"}"
|
|
||||||
F_3_VIEW_ARTIST="${F_3_VIEW_ARTIST:-"'$q_ep'"}"
|
|
||||||
F_4_VIEW_ARTIST="${F_4_VIEW_ARTIST:-"'$q_single'"}"
|
|
||||||
F_5_VIEW_ARTIST="${F_5_VIEW_ARTIST:-}"
|
|
||||||
F_6_VIEW_ARTIST="${F_6_VIEW_ARTIST:-}"
|
|
||||||
F_7_VIEW_ARTIST="${F_7_VIEW_ARTIST:-}"
|
|
||||||
F_8_VIEW_ARTIST="${F_8_VIEW_ARTIST:-}"
|
|
||||||
F_9_VIEW_ARTIST="${F_9_VIEW_ARTIST:-}"
|
|
||||||
export F_1_VIEW_ARTIST F_2_VIEW_ARTIST F_3_VIEW_ARTIST F_4_VIEW_ARTIST \
|
|
||||||
F_5_VIEW_ARTIST F_6_VIEW_ARTIST F_7_VIEW_ARTIST F_8_VIEW_ARTIST \
|
|
||||||
F_9_VIEW_ARTIST
|
|
||||||
|
|
||||||
F_1_VIEW_RELEASEGROUP="${F_1_VIEW_RELEASEGROUP:-"${q_official:-}"}"
|
|
||||||
F_2_VIEW_RELEASEGROUP="${F_2_VIEW_RELEASEGROUP:-}"
|
|
||||||
F_3_VIEW_RELEASEGROUP="${F_3_VIEW_RELEASEGROUP:-}"
|
|
||||||
F_4_VIEW_RELEASEGROUP="${F_4_VIEW_RELEASEGROUP:-}"
|
|
||||||
F_5_VIEW_RELEASEGROUP="${F_5_VIEW_RELEASEGROUP:-}"
|
|
||||||
F_6_VIEW_RELEASEGROUP="${F_6_VIEW_RELEASEGROUP:-}"
|
|
||||||
F_7_VIEW_RELEASEGROUP="${F_7_VIEW_RELEASEGROUP:-}"
|
|
||||||
F_8_VIEW_RELEASEGROUP="${F_8_VIEW_RELEASEGROUP:-}"
|
|
||||||
F_9_VIEW_RELEASEGROUP="${F_9_VIEW_RELEASEGROUP:-}"
|
|
||||||
export F_1_VIEW_RELEASEGROUP F_2_VIEW_RELEASEGROUP F_3_VIEW_RELEASEGROUP \
|
|
||||||
F_4_VIEW_RELEASEGROUP F_5_VIEW_RELEASEGROUP F_6_VIEW_RELEASEGROUP \
|
|
||||||
F_7_VIEW_RELEASEGROUP F_8_VIEW_RELEASEGROUP F_9_VIEW_RELEASEGROUP
|
|
||||||
|
|
||||||
F_1_VIEW_RELEASE="${F_1_VIEW_RELEASE:-}"
|
|
||||||
F_2_VIEW_RELEASE="${F_2_VIEW_RELEASE:-}"
|
|
||||||
F_3_VIEW_RELEASE="${F_3_VIEW_RELEASE:-}"
|
|
||||||
F_4_VIEW_RELEASE="${F_4_VIEW_RELEASE:-}"
|
|
||||||
F_5_VIEW_RELEASE="${F_5_VIEW_RELEASE:-}"
|
|
||||||
F_6_VIEW_RELEASE="${F_6_VIEW_RELEASE:-}"
|
|
||||||
F_7_VIEW_RELEASE="${F_7_VIEW_RELEASE:-}"
|
|
||||||
F_8_VIEW_RELEASE="${F_8_VIEW_RELEASE:-}"
|
|
||||||
F_9_VIEW_RELEASE="${F_9_VIEW_RELEASE:-}"
|
|
||||||
export F_1_VIEW_RELEASE F_2_VIEW_RELEASE F_3_VIEW_RELEASE F_4_VIEW_RELEASE \
|
|
||||||
F_5_VIEW_RELEASE F_6_VIEW_RELEASE F_7_VIEW_RELEASE F_8_VIEW_RELEASE \
|
|
||||||
F_9_VIEW_RELEASE
|
|
||||||
|
|
||||||
F_1_LIST_ARTISTS="${F_1_LIST_ARTISTS:-}"
|
|
||||||
F_2_LIST_ARTISTS="${F_2_LIST_ARTISTS:-}"
|
|
||||||
F_3_LIST_ARTISTS="${F_3_LIST_ARTISTS:-}"
|
|
||||||
F_4_LIST_ARTISTS="${F_4_LIST_ARTISTS:-}"
|
|
||||||
F_5_LIST_ARTISTS="${F_5_LIST_ARTISTS:-}"
|
|
||||||
F_6_LIST_ARTISTS="${F_6_LIST_ARTISTS:-}"
|
|
||||||
F_7_LIST_ARTISTS="${F_7_LIST_ARTISTS:-}"
|
|
||||||
F_8_LIST_ARTISTS="${F_8_LIST_ARTISTS:-}"
|
|
||||||
F_9_LIST_ARTISTS="${F_9_LIST_ARTISTS:-}"
|
|
||||||
export F_1_LIST_ARTISTS F_2_LIST_ARTISTS F_3_LIST_ARTISTS F_4_LIST_ARTISTS \
|
|
||||||
F_5_LIST_ARTISTS F_6_LIST_ARTISTS F_7_LIST_ARTISTS F_8_LIST_ARTISTS \
|
|
||||||
F_9_LIST_ARTISTS
|
|
||||||
|
|
||||||
F_1_LIST_ALBUMS="${F_1_LIST_ALBUMS:-}"
|
|
||||||
F_2_LIST_ALBUMS="${F_2_LIST_ALBUMS:-}"
|
|
||||||
F_3_LIST_ALBUMS="${F_3_LIST_ALBUMS:-}"
|
|
||||||
F_4_LIST_ALBUMS="${F_4_LIST_ALBUMS:-}"
|
|
||||||
F_5_LIST_ALBUMS="${F_5_LIST_ALBUMS:-}"
|
|
||||||
F_6_LIST_ALBUMS="${F_6_LIST_ALBUMS:-}"
|
|
||||||
F_7_LIST_ALBUMS="${F_7_LIST_ALBUMS:-}"
|
|
||||||
F_8_LIST_ALBUMS="${F_8_LIST_ALBUMS:-}"
|
|
||||||
F_9_LIST_ALBUMS="${F_9_LIST_ALBUMS:-}"
|
|
||||||
export F_1_LIST_ALBUMS F_2_LIST_ALBUMS F_3_LIST_ALBUMS F_4_LIST_ALBUMS \
|
|
||||||
F_5_LIST_ALBUMS F_6_LIST_ALBUMS F_7_LIST_ALBUMS F_8_LIST_ALBUMS \
|
|
||||||
F_9_LIST_ALBUMS
|
|
||||||
|
|||||||
@@ -11,40 +11,60 @@ fzf_command_set_header() {
|
|||||||
"$VIEW_LIST_ARTISTS") header="Search locally available artist" ;;
|
"$VIEW_LIST_ARTISTS") header="Search locally available artist" ;;
|
||||||
"$VIEW_LIST_ALBUMS") header="Search locally available album" ;;
|
"$VIEW_LIST_ALBUMS") header="Search locally available album" ;;
|
||||||
"$VIEW_ARTIST")
|
"$VIEW_ARTIST")
|
||||||
name="$(mb_artist "$mbid" | $JQ '.name')"
|
header="$(
|
||||||
header=$(printf "$HEADER_ARTIST" "$name")
|
mb_artist "$mbid" |
|
||||||
|
$JQ '[.id, type, .name, .disambiguation] | join("\t")' |
|
||||||
|
awk_artist_header
|
||||||
|
)"
|
||||||
|
if [ ! "$header" ]; then
|
||||||
|
header="Possibly $mbid is not a MusicBrainz Artist ID"
|
||||||
|
err "$header"
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
"$VIEW_RELEASEGROUP")
|
"$VIEW_RELEASEGROUP")
|
||||||
title="$(mb_releasegroup "$mbid" |
|
header="$(
|
||||||
$JQ '.title')"
|
mb_releasegroup "$mbid" |
|
||||||
artist="$(mb_releasegroup "$mbid" |
|
$JQ '[
|
||||||
$JQ '."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")')"
|
.id,
|
||||||
header=$(printf "$HEADER_ARTIST_RELEASEGROUP" "$artist" "$title")
|
."primary-type",
|
||||||
|
(."secondary-types" // []|join(";")),
|
||||||
|
."first-release-date",
|
||||||
|
.title,
|
||||||
|
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
|
||||||
|
] | join("\t")' |
|
||||||
|
awk_releasegroup_header
|
||||||
|
)"
|
||||||
|
if [ ! "$header" ]; then
|
||||||
|
header="Possibly $mbid is not a MusicBrainz Release-Group ID"
|
||||||
|
err "$header"
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
"$VIEW_RELEASE")
|
"$VIEW_RELEASE")
|
||||||
title="$(mb_release "$mbid" |
|
header="$(
|
||||||
$JQ '.title')"
|
mb_release "$mbid" |
|
||||||
artist="$(mb_release "$mbid" |
|
$JQ '[
|
||||||
$JQ '."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")')"
|
.id,
|
||||||
releaseinfo="$(mb_release "$mbid" |
|
.status,
|
||||||
$JQ '[
|
.date,
|
||||||
.date[:4],
|
."cover-art-archive".count,
|
||||||
(."label-info" | map(.label.name) | unique | join(", ")),
|
(."label-info" | map(.label.name) | unique | join(", ")),
|
||||||
(.media | map(."track-count") | add),
|
(.media | map(."track-count") | add),
|
||||||
(.media | map(.format) | unique | join(", ")),
|
(.media | map(.format) | unique | join(", ")),
|
||||||
.country
|
.country,
|
||||||
] | join("\t")' |
|
.title,
|
||||||
awk -F "\t" -v format="$HEADER_RELEASE_FORMAT" '{
|
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
|
||||||
gsub("&", "\\\\&")
|
] | join("\t")' |
|
||||||
sub("<<year>>", $1, format)
|
awk_release_header
|
||||||
sub("<<label>>", $2, format)
|
)"
|
||||||
sub("<<tracks>>", $3, format)
|
if [ ! "$header" ]; then
|
||||||
sub("<<media>>", $4, format)
|
header="Possibly $mbid is not a MusicBrainz Release ID"
|
||||||
sub("<<country>>", $5, format)
|
err "$header"
|
||||||
print format
|
fi
|
||||||
}')"
|
;;
|
||||||
header=$(printf "$HEADER_RELEASE" "$artist" "$title" "$releaseinfo")
|
*)
|
||||||
|
header="We entered an unknown state"
|
||||||
|
err "$header"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
printf "+change-header(%s)" "${header:-"???"}"
|
printf "+change-header(%s)" "$header"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ if [ ! "${INFO_LOADED:-}" ]; then
|
|||||||
APP_NAME="fuzic"
|
APP_NAME="fuzic"
|
||||||
APP_VERSION="0.1"
|
APP_VERSION="0.1"
|
||||||
APP_WEBSITE="https://git.indyfac.ch/amin/fuzic"
|
APP_WEBSITE="https://git.indyfac.ch/amin/fuzic"
|
||||||
WINDOW_TITLE="🔎🎶 $APP_NAME | a simple music finder and player"
|
WINDOW_TITLE="🔎🎶 $APP_NAME | a simple music browser and player"
|
||||||
export APP_NAME APP_VERSION APP_WEBSITE WINDOW_TITLE
|
export APP_NAME APP_VERSION APP_WEBSITE WINDOW_TITLE
|
||||||
|
|
||||||
export INFO_LOADED=1
|
export INFO_LOADED=1
|
||||||
|
|||||||
@@ -59,8 +59,15 @@
|
|||||||
# - KEYS_SCROLL_PREVIEW_UP: Scroll preview up
|
# - KEYS_SCROLL_PREVIEW_UP: Scroll preview up
|
||||||
# - KEYS_PREVIEW_OPEN: Open preview window
|
# - KEYS_PREVIEW_OPEN: Open preview window
|
||||||
# - KEYS_PREVIEW_CLOSE: Close preview window
|
# - KEYS_PREVIEW_CLOSE: Close preview window
|
||||||
|
# - KEYS_PREVIEW_TOGGLE_WRAP: Toggle line wrapping in preview window
|
||||||
|
# - KEYS_PREVIEW_TOGGLE_SIZE: Toggle size (small, large) of preview window
|
||||||
# - KEYS_REFRESH: Refresh current entry
|
# - KEYS_REFRESH: Refresh current entry
|
||||||
#
|
#
|
||||||
|
# Lyrics:
|
||||||
|
# - KEYS_N_LYRICS: Show lyrics of selected track
|
||||||
|
# - KEYS_LYRICS_EDIT: Edit lyrics of selected track
|
||||||
|
# - KEYS_N_LYRICS_FETCH_CUSTOM: Fetch lyrics using custom command
|
||||||
|
#
|
||||||
# Playback:
|
# Playback:
|
||||||
# - KEYS_PLAY: Play selected release or selected track
|
# - KEYS_PLAY: Play selected release or selected track
|
||||||
# - KEYS_QUEUE: Queue selected release or selected track
|
# - KEYS_QUEUE: Queue selected release or selected track
|
||||||
@@ -85,7 +92,10 @@
|
|||||||
# - KEYS_PLAYLIST_GOTO_RELEASE: Jump to release or selected entry
|
# - KEYS_PLAYLIST_GOTO_RELEASE: Jump to release or selected entry
|
||||||
# - KEYS_PLAYLIST_STORE: Store current playlist as file
|
# - KEYS_PLAYLIST_STORE: Store current playlist as file
|
||||||
# - KEYS_PLAYLIST_LOAD: Load playlist from file
|
# - KEYS_PLAYLIST_LOAD: Load playlist from file
|
||||||
# - KEYS_PLAYLIST_QUIT: Quit playlist view
|
#
|
||||||
|
# Playlist store (here, we don't have a `normal` mode):
|
||||||
|
# - KEYS_PLAYLISTSTORE_SELECT: Use selected playlist
|
||||||
|
# - KEYS_PLAYLISTSTORE_DELETE: Delete stored playlist
|
||||||
|
|
||||||
if [ ! "${KEYS_LOADED:-}" ]; then
|
if [ ! "${KEYS_LOADED:-}" ]; then
|
||||||
# Mode selection:
|
# Mode selection:
|
||||||
@@ -101,7 +111,7 @@ if [ ! "${KEYS_LOADED:-}" ]; then
|
|||||||
KEYS_N_DOWN="${KEYS_N_DOWN:-"j"}"
|
KEYS_N_DOWN="${KEYS_N_DOWN:-"j"}"
|
||||||
KEYS_N_UP="${KEYS_N_UP:-"k"}"
|
KEYS_N_UP="${KEYS_N_UP:-"k"}"
|
||||||
KEYS_N_BOT="${KEYS_N_BOT:-"G"}"
|
KEYS_N_BOT="${KEYS_N_BOT:-"G"}"
|
||||||
KEYS_N_TOP="${KEYS_N_TOP:-"1"}"
|
KEYS_N_TOP="${KEYS_N_TOP:-"1,g"}"
|
||||||
export KEYS_DOWN KEYS_UP KEYS_HALFPAGE_DOWN KEYS_HALFPAGE_UP KEYS_N_DOWN \
|
export KEYS_DOWN KEYS_UP KEYS_HALFPAGE_DOWN KEYS_HALFPAGE_UP KEYS_N_DOWN \
|
||||||
KEYS_N_UP KEYS_N_BOT KEYS_N_TOP
|
KEYS_N_UP KEYS_N_BOT KEYS_N_TOP
|
||||||
|
|
||||||
@@ -151,10 +161,20 @@ if [ ! "${KEYS_LOADED:-}" ]; then
|
|||||||
KEYS_SCROLL_PREVIEW_UP="${KEYS_SCROLL_PREVIEW_UP:-"page-up"}"
|
KEYS_SCROLL_PREVIEW_UP="${KEYS_SCROLL_PREVIEW_UP:-"page-up"}"
|
||||||
KEYS_PREVIEW_OPEN="${KEYS_PREVIEW_OPEN:-"alt-up"}"
|
KEYS_PREVIEW_OPEN="${KEYS_PREVIEW_OPEN:-"alt-up"}"
|
||||||
KEYS_PREVIEW_CLOSE="${KEYS_PREVIEW_CLOSE:-"alt-down"}"
|
KEYS_PREVIEW_CLOSE="${KEYS_PREVIEW_CLOSE:-"alt-down"}"
|
||||||
|
KEYS_PREVIEW_TOGGLE_WRAP="${KEYS_PREVIEW_TOGGLE_WRAP:-"alt-w"}"
|
||||||
|
KEYS_PREVIEW_TOGGLE_SIZE="${KEYS_PREVIEW_TOGGLE_SIZE:-"alt-/"}"
|
||||||
KEYS_REFRESH="${KEYS_REFRESH:-"ctrl-r"}"
|
KEYS_REFRESH="${KEYS_REFRESH:-"ctrl-r"}"
|
||||||
export KEYS_BROWSE KEYS_OPEN KEYS_N_YANK KEYS_YANK_CURRENT KEYS_SHOW_PLAYLIST \
|
export KEYS_BROWSE KEYS_OPEN KEYS_N_YANK KEYS_YANK_CURRENT \
|
||||||
KEYS_KEYBINDINGS KEYS_QUIT KEYS_N_QUIT KEYS_SCROLL_PREVIEW_DOWN \
|
KEYS_SHOW_PLAYLIST KEYS_KEYBINDINGS KEYS_QUIT KEYS_N_QUIT \
|
||||||
KEYS_SCROLL_PREVIEW_UP KEYS_PREVIEW_CLOSE KEYS_PREVIEW_OPEN KEYS_REFRESH
|
KEYS_SCROLL_PREVIEW_DOWN KEYS_SCROLL_PREVIEW_UP KEYS_PREVIEW_CLOSE \
|
||||||
|
KEYS_PREVIEW_OPEN KEYS_PREVIEW_TOGGLE_WRAP KEYS_PREVIEW_TOGGLE_SIZE \
|
||||||
|
KEYS_REFRESH
|
||||||
|
|
||||||
|
# Lyrics:
|
||||||
|
KEYS_N_LYRICS="${KEYS_N_LYRICS:-"L"}"
|
||||||
|
KEYS_LYRICS_EDIT="${KEYS_LYRICS_EDIT:-"alt-L"}"
|
||||||
|
KEYS_N_LYRICS_FETCH_CUSTOM="${KEYS_N_LYRICS_FETCH_CUSTOM:-"Y"}"
|
||||||
|
export KEYS_N_LYRICS KEYS_LYRICS_EDIT KEYS_N_LYRICS_FETCH_CUSTOM
|
||||||
|
|
||||||
# Playback:
|
# Playback:
|
||||||
KEYS_PLAY="${KEYS_PLAY:-"enter"}"
|
KEYS_PLAY="${KEYS_PLAY:-"enter"}"
|
||||||
@@ -193,11 +213,17 @@ if [ ! "${KEYS_LOADED:-}" ]; then
|
|||||||
KEYS_PLAYLIST_UNSHUFFLE="${KEYS_PLAYLIST_UNSHUFFLE:-"S"}"
|
KEYS_PLAYLIST_UNSHUFFLE="${KEYS_PLAYLIST_UNSHUFFLE:-"S"}"
|
||||||
KEYS_PLAYLIST_GOTO_RELEASE="${KEYS_PLAYLIST_GOTO_RELEASE:-"ctrl-g"}"
|
KEYS_PLAYLIST_GOTO_RELEASE="${KEYS_PLAYLIST_GOTO_RELEASE:-"ctrl-g"}"
|
||||||
KEYS_PLAYLIST_STORE="${KEYS_PLAYLIST_STORE:-"ctrl-s"}"
|
KEYS_PLAYLIST_STORE="${KEYS_PLAYLIST_STORE:-"ctrl-s"}"
|
||||||
KEYS_PLAYLIST_LOAD="${KEYS_PLAYLIST_LOAD:-"ctrl-o"}"
|
KEYS_PLAYLIST_OPEN_STORE="${KEYS_PLAYLIST_LOAD:-"ctrl-o"}"
|
||||||
|
KEYS_PLAYLIST_DELETE="${KEYS_PLAYLIST_DELETE:-"del"}"
|
||||||
export KEYS_PLAYLIST_RELOAD KEYS_PLAYLIST_REMOVE KEYS_PLAYLIST_UP \
|
export KEYS_PLAYLIST_RELOAD KEYS_PLAYLIST_REMOVE KEYS_PLAYLIST_UP \
|
||||||
KEYS_PLAYLIST_DOWN KEYS_PLAYLIST_CLEAR KEYS_PLAYLIST_CLEAR_ABOVE \
|
KEYS_PLAYLIST_DOWN KEYS_PLAYLIST_CLEAR KEYS_PLAYLIST_CLEAR_ABOVE \
|
||||||
KEYS_PLAYLIST_CLEAR_BELOW KEYS_PLAYLIST_SHUFFLE KEYS_PLAYLIST_UNSHUFFLE \
|
KEYS_PLAYLIST_CLEAR_BELOW KEYS_PLAYLIST_SHUFFLE KEYS_PLAYLIST_UNSHUFFLE \
|
||||||
KEYS_PLAYLIST_GOTO_RELEASE KEYS_PLAYLIST_STORE KEYS_PLAYLIST_LOAD
|
KEYS_PLAYLIST_GOTO_RELEASE KEYS_PLAYLIST_STORE KEYS_PLAYLIST_OPEN_STORE
|
||||||
|
|
||||||
|
# Playlist store (here, we don't have a `normal` mode):
|
||||||
|
KEYS_PLAYLISTSTORE_SELECT="${KEYS_PLAYLISTSTORE_SELECT:-"enter"}"
|
||||||
|
KEYS_PLAYLISTSTORE_DELETE="${KEYS_PLAYLISTSTORE_DELETE:-"del"}"
|
||||||
|
export KEYS_PLAYLISTSTORE_SELECT KEYS_PLAYLISTSTORE_DELETE
|
||||||
|
|
||||||
export KEYS_LOADED=1
|
export KEYS_LOADED=1
|
||||||
fi
|
fi
|
||||||
@@ -239,6 +265,8 @@ print_keybindings() {
|
|||||||
"$KEYS_SCROLL_PREVIEW_DOWN" "Scroll preview down" \
|
"$KEYS_SCROLL_PREVIEW_DOWN" "Scroll preview down" \
|
||||||
"$KEYS_SCROLL_PREVIEW_UP" "Scroll preview up" \
|
"$KEYS_SCROLL_PREVIEW_UP" "Scroll preview up" \
|
||||||
"$KEYS_KEYBINDINGS" "Show these keybindings" \
|
"$KEYS_KEYBINDINGS" "Show these keybindings" \
|
||||||
|
"$KEYS_PREVIEW_TOGGLE_WRAP" "Toggle preview wrapping" \
|
||||||
|
"$KEYS_PREVIEW_TOGGLE_SIZE" "Toggle preview size" \
|
||||||
"$KEYS_PREVIEW_OPEN" "Open preview window" \
|
"$KEYS_PREVIEW_OPEN" "Open preview window" \
|
||||||
"$KEYS_PREVIEW_CLOSE" "Close preview window"
|
"$KEYS_PREVIEW_CLOSE" "Close preview window"
|
||||||
__keybindinggroup_from_args "Navigation" \
|
__keybindinggroup_from_args "Navigation" \
|
||||||
@@ -273,7 +301,8 @@ print_keybindings() {
|
|||||||
"$KEYS_N_TOP" "Go to first entry" \
|
"$KEYS_N_TOP" "Go to first entry" \
|
||||||
"$KEYS_N_BOT" "Go to last entry" \
|
"$KEYS_N_BOT" "Go to last entry" \
|
||||||
"$KEYS_OUT,$KEYS_N_OUT,$KEYS_QUIT,$KEYS_N_QUIT" "Leave playlist view" \
|
"$KEYS_OUT,$KEYS_N_OUT,$KEYS_QUIT,$KEYS_N_QUIT" "Leave playlist view" \
|
||||||
"$KEYS_SELECT_ARTIST" "Go to artist of selected item"
|
"$KEYS_SELECT_ARTIST" "Go to artist of selected item" \
|
||||||
|
"$KEYS_PLAYLIST_GOTO_RELEASE" "Show release of selected track"
|
||||||
__keybindinggroup_from_args "Views" \
|
__keybindinggroup_from_args "Views" \
|
||||||
"$KEYS_LIST_ARTISTS" "Display artists in local database" \
|
"$KEYS_LIST_ARTISTS" "Display artists in local database" \
|
||||||
"$KEYS_LIST_ALBUMS" "Display albums in local database" \
|
"$KEYS_LIST_ALBUMS" "Display albums in local database" \
|
||||||
@@ -289,7 +318,7 @@ print_keybindings() {
|
|||||||
"$KEYS_PLAYLIST_CLEAR_BELOW" "Remove all tracks below" \
|
"$KEYS_PLAYLIST_CLEAR_BELOW" "Remove all tracks below" \
|
||||||
"$KEYS_PLAYLIST_SHUFFLE" "Shuffle" \
|
"$KEYS_PLAYLIST_SHUFFLE" "Shuffle" \
|
||||||
"$KEYS_PLAYLIST_UNSHUFFLE" "Undo shuffle" \
|
"$KEYS_PLAYLIST_UNSHUFFLE" "Undo shuffle" \
|
||||||
"$KEYS_PLAYLIST_GOTO_RELEASE" "Show release of selected track"
|
"$KEYS_PLAYLIST_OPEN_STORE" "Manage stored playlists"
|
||||||
__keybindinggroup_from_args "Playback" \
|
__keybindinggroup_from_args "Playback" \
|
||||||
"$KEYS_PLAY,$KEYS_N_PLAY" "Play selected item" \
|
"$KEYS_PLAY,$KEYS_N_PLAY" "Play selected item" \
|
||||||
"$KEYS_QUEUE,$KEYS_N_QUEUE" "Queue selected item" \
|
"$KEYS_QUEUE,$KEYS_N_QUEUE" "Queue selected item" \
|
||||||
@@ -299,12 +328,35 @@ print_keybindings() {
|
|||||||
"$KEYS_PLAY_PREV,$KEYS_N_PLAY_PREV" "Play previous track" \
|
"$KEYS_PLAY_PREV,$KEYS_N_PLAY_PREV" "Play previous track" \
|
||||||
"$KEYS_SEEK_FORWARD,$KEYS_N_SEEK_FORWARD" "Seek forward" \
|
"$KEYS_SEEK_FORWARD,$KEYS_N_SEEK_FORWARD" "Seek forward" \
|
||||||
"$KEYS_SEEK_BACKWARD,$KEYS_N_SEEK_BACKWARD" "Seek backward"
|
"$KEYS_SEEK_BACKWARD,$KEYS_N_SEEK_BACKWARD" "Seek backward"
|
||||||
|
__keybindinggroup_from_args "Lyrics" \
|
||||||
|
"$KEYS_N_LYRICS" "Show lyrics" \
|
||||||
|
"$KEYS_LYRICS_EDIT" "Edit lyrics" \
|
||||||
|
"$KEYS_N_LYRICS_FETCH_CUSTOM" "Fetch lyrics using custom command"
|
||||||
__keybindinggroup_from_args "Special operations" \
|
__keybindinggroup_from_args "Special operations" \
|
||||||
"$KEYS_BROWSE" "Open selected item in browser" \
|
"$KEYS_BROWSE" "Open selected item in browser" \
|
||||||
"$KEYS_OPEN" "Open selected item in file manager" \
|
"$KEYS_OPEN" "Open selected item in file manager" \
|
||||||
"$KEYS_N_YANK" "Copy MusicBrainz track ID" \
|
"$KEYS_N_YANK" "Copy MusicBrainz track ID" \
|
||||||
"$KEYS_YANK_CURRENT" "Copy MusicBrainz release ID"
|
"$KEYS_YANK_CURRENT" "Copy MusicBrainz release ID"
|
||||||
;;
|
;;
|
||||||
|
"$VIEW_PLAYLIST_PLAYLISTSTORE")
|
||||||
|
__keybindinggroup_from_args "Previews" \
|
||||||
|
"$KEYS_SCROLL_PREVIEW_DOWN" "Scroll preview down" \
|
||||||
|
"$KEYS_SCROLL_PREVIEW_UP" "Scroll preview up" \
|
||||||
|
"$KEYS_KEYBINDINGS" "Show these keybindings" \
|
||||||
|
"$KEYS_PREVIEW_TOGGLE_WRAP" "Toggle preview wrapping" \
|
||||||
|
"$KEYS_PREVIEW_TOGGLE_SIZE" "Toggle preview size" \
|
||||||
|
"$KEYS_PREVIEW_OPEN" "Open preview window" \
|
||||||
|
"$KEYS_PREVIEW_CLOSE" "Close preview window"
|
||||||
|
__keybindinggroup_from_args "Navigation" \
|
||||||
|
"$KEYS_DOWN" "Down" \
|
||||||
|
"$KEYS_UP" "Up" \
|
||||||
|
"$KEYS_HALFPAGE_DOWN" "Down half a page" \
|
||||||
|
"$KEYS_HALFPAGE_UP" "Up half a page" \
|
||||||
|
"$KEYS_OUT,$KEYS_QUIT" "Leave playlist store"
|
||||||
|
__keybindinggroup_from_args "Playlist store" \
|
||||||
|
"$KEYS_PLAYLISTSTORE_SELECT" "Load playlist" \
|
||||||
|
"$KEYS_PLAYLISTSTORE_DELETE" "Delete playlist"
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
__keybindinggroup_from_args "Switch between modes" \
|
__keybindinggroup_from_args "Switch between modes" \
|
||||||
"$KEYS_I_NORMAL" "Swtich to normal mode (insert)" \
|
"$KEYS_I_NORMAL" "Swtich to normal mode (insert)" \
|
||||||
@@ -313,6 +365,8 @@ print_keybindings() {
|
|||||||
"$KEYS_SCROLL_PREVIEW_DOWN" "Scroll preview down" \
|
"$KEYS_SCROLL_PREVIEW_DOWN" "Scroll preview down" \
|
||||||
"$KEYS_SCROLL_PREVIEW_UP" "Scroll preview up" \
|
"$KEYS_SCROLL_PREVIEW_UP" "Scroll preview up" \
|
||||||
"$KEYS_KEYBINDINGS" "Show these keybindings" \
|
"$KEYS_KEYBINDINGS" "Show these keybindings" \
|
||||||
|
"$KEYS_PREVIEW_TOGGLE_WRAP" "Toggle preview wrapping" \
|
||||||
|
"$KEYS_PREVIEW_TOGGLE_SIZE" "Toggle preview size" \
|
||||||
"$KEYS_PREVIEW_OPEN" "Open preview window" \
|
"$KEYS_PREVIEW_OPEN" "Open preview window" \
|
||||||
"$KEYS_PREVIEW_CLOSE" "Close preview window"
|
"$KEYS_PREVIEW_CLOSE" "Close preview window"
|
||||||
__keybindinggroup_from_args "Navigation" \
|
__keybindinggroup_from_args "Navigation" \
|
||||||
@@ -366,6 +420,10 @@ print_keybindings() {
|
|||||||
"$KEYS_N_PLAY_PREV" "Play previous track" \
|
"$KEYS_N_PLAY_PREV" "Play previous track" \
|
||||||
"$KEYS_N_SEEK_FORWARD" "Seek forward" \
|
"$KEYS_N_SEEK_FORWARD" "Seek forward" \
|
||||||
"$KEYS_N_SEEK_BACKWARD" "Seek backward"
|
"$KEYS_N_SEEK_BACKWARD" "Seek backward"
|
||||||
|
__keybindinggroup_from_args "Lyrics" \
|
||||||
|
"$KEYS_N_LYRICS" "Show lyrics (normal mode)" \
|
||||||
|
"$KEYS_LYRICS_EDIT" "Edit lyrics" \
|
||||||
|
"$KEYS_N_LYRICS_FETCH_CUSTOM" "Fetch lyrics using custom command (normal)"
|
||||||
__keybindinggroup_from_args "Special operations" \
|
__keybindinggroup_from_args "Special operations" \
|
||||||
"$KEYS_SHOW_PLAYLIST" "Show playlist" \
|
"$KEYS_SHOW_PLAYLIST" "Show playlist" \
|
||||||
"$KEYS_BROWSE" "Open selected item in browser" \
|
"$KEYS_BROWSE" "Open selected item in browser" \
|
||||||
|
|||||||
173
src/sh/lists.sh
173
src/sh/lists.sh
@@ -14,39 +14,7 @@ list_releasegroups() {
|
|||||||
.title,
|
.title,
|
||||||
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
|
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
|
||||||
] | join("\t")' |
|
] | join("\t")' |
|
||||||
awk \
|
awk_releasegroups "$SORT_RG_DEFAULT" "$1" "$name"
|
||||||
-F "\t" \
|
|
||||||
-v artist="$name" \
|
|
||||||
-v artistid="$1" \
|
|
||||||
-v file_local_releasegroups="${LOCALDATA_RELEASEGROUPS:-}" \
|
|
||||||
-v format_release="$RGV_RELEASE" \
|
|
||||||
-v format_release_w_artist="$RGV_RELEASE_W_ARTIST" \
|
|
||||||
-v format_year="$RGV_YEAR" \
|
|
||||||
-v format_album="$FORMAT_TYPE_ALBUM" \
|
|
||||||
-v format_single="$FORMAT_TYPE_SINGLE" \
|
|
||||||
-v format_ep="$FORMAT_TYPE_EP" \
|
|
||||||
-v format_broadcast="$FORMAT_TYPE_BROADCAST" \
|
|
||||||
-v format_other="$FORMAT_TYPE_OTHER" \
|
|
||||||
-v format_has_secondary="$FORMAT_TYPE_HAS_SECONDARY" \
|
|
||||||
-v format_secondary="$FORMAT_TYPE_SECONDARY" \
|
|
||||||
-v format_compilation="$FORMAT_TYPE_SECONDARY_COMPILATION" \
|
|
||||||
-v format_soundtrack="$FORMAT_TYPE_SECONDARY_SOUNDTRACK" \
|
|
||||||
-v format_spokenword="$FORMAT_TYPE_SECONDARY_SPOKENWORD" \
|
|
||||||
-v format_interview="$FORMAT_TYPE_SECONDARY_INTERVIEW" \
|
|
||||||
-v format_audiobook="$FORMAT_TYPE_SECONDARY_AUDIOBOOK" \
|
|
||||||
-v format_audiodrama="$FORMAT_TYPE_SECONDARY_AUDIODRAMA" \
|
|
||||||
-v format_live="$FORMAT_TYPE_SECONDARY_LIVE" \
|
|
||||||
-v format_remix="$FORMAT_TYPE_SECONDARY_REMIX" \
|
|
||||||
-v format_djmix="$FORMAT_TYPE_SECONDARY_DJMIX" \
|
|
||||||
-v format_mixtape="$FORMAT_TYPE_SECONDARY_MIXTAPE" \
|
|
||||||
-v format_demo="$FORMAT_TYPE_SECONDARY_DEMO" \
|
|
||||||
-v format_fieldrec="$FORMAT_TYPE_SECONDARY_FIELDREC" \
|
|
||||||
-v format_local="$FORMAT_LOCAL" \
|
|
||||||
"$AWK_RELEASEGROUPS" |
|
|
||||||
sort -n -r |
|
|
||||||
cut -d "$(printf '\t')" -f 2- |
|
|
||||||
column -t -s "$(printf '\t')" |
|
|
||||||
sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\)$|\t\1\t\2|'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# List releases in given relese group
|
# List releases in given relese group
|
||||||
@@ -70,95 +38,18 @@ list_releases() {
|
|||||||
.title,
|
.title,
|
||||||
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
|
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
|
||||||
] | join("\t")' |
|
] | join("\t")' |
|
||||||
awk \
|
awk_releases "$1" "$title" "$artist"
|
||||||
-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 format_release="$RV_FORMAT" \
|
|
||||||
-v format_release_title_artist="$RV_TITLE_ARTIST" \
|
|
||||||
-v format_release_title="$RV_TITLE" \
|
|
||||||
-v format_release_artist="$RV_ARTIST" \
|
|
||||||
-v rg_artist="$artist" \
|
|
||||||
-v rg_title="$title" \
|
|
||||||
-v rgid="$1" \
|
|
||||||
-v format_local="$FORMAT_LOCAL" \
|
|
||||||
"$AWK_RELEASES" |
|
|
||||||
sort -n -r |
|
|
||||||
cut -d "$(printf '\t')" -f 2- |
|
|
||||||
column -t -s "$(printf '\t')" |
|
|
||||||
sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\):\(.*$\)$|\t\1\t\2\t\3|'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# List recordings of given release
|
# List recordings of given release
|
||||||
#
|
#
|
||||||
# argument $1: MusicBrainz release ID
|
# argument $1: MusicBrainz release ID
|
||||||
list_recordings() {
|
list_recordings() {
|
||||||
info "list recordings.."
|
|
||||||
deco="$(grep "$1" "$LOCALDATA_RELEASES" | cut -d "$(printf '\t')" -f 2)"
|
deco="$(grep "$1" "$LOCALDATA_RELEASES" | cut -d "$(printf '\t')" -f 2)"
|
||||||
info "deco=$deco"
|
|
||||||
if [ "$deco" ]; then
|
if [ "$deco" ]; then
|
||||||
rectmp=$(mktemp)
|
rectmp=$(mktemp)
|
||||||
$JQ '.tracks | keys | join("\n")' "$deco" >"$rectmp"
|
$JQ '.tracks | keys | join("\n")' "$deco" >"$rectmp"
|
||||||
info "rectmp=$rectmp"
|
|
||||||
info "$(cat "$rectmp")"
|
|
||||||
fi
|
fi
|
||||||
info "going to awk..."
|
|
||||||
info "$(
|
|
||||||
mb_release "$1" |
|
|
||||||
$JQ \
|
|
||||||
--arg rid "$1" \
|
|
||||||
--arg deco "$deco" \
|
|
||||||
'.media |
|
|
||||||
length as $l |
|
|
||||||
.[] |
|
|
||||||
.position as $pos |
|
|
||||||
.tracks[] | [
|
|
||||||
$rid,
|
|
||||||
.id,
|
|
||||||
$l,
|
|
||||||
$pos,
|
|
||||||
.number,
|
|
||||||
.length,
|
|
||||||
.recording.title,
|
|
||||||
(.recording."artist-credit" | map([.name, .joinphrase] | join("")) | join("")),
|
|
||||||
$deco
|
|
||||||
] |
|
|
||||||
join("\t")'
|
|
||||||
)"
|
|
||||||
info "$(
|
|
||||||
mb_release "$1" |
|
|
||||||
$JQ \
|
|
||||||
--arg rid "$1" \
|
|
||||||
--arg deco "$deco" \
|
|
||||||
'.media |
|
|
||||||
length as $l |
|
|
||||||
.[] |
|
|
||||||
.position as $pos |
|
|
||||||
.tracks[] | [
|
|
||||||
$rid,
|
|
||||||
.id,
|
|
||||||
$l,
|
|
||||||
$pos,
|
|
||||||
.number,
|
|
||||||
.length,
|
|
||||||
.recording.title,
|
|
||||||
(.recording."artist-credit" | map([.name, .joinphrase] | join("")) | join("")),
|
|
||||||
$deco
|
|
||||||
] |
|
|
||||||
join("\t")' |
|
|
||||||
awk \
|
|
||||||
-F "\t" \
|
|
||||||
-v file_local_recordings="${rectmp:-}" \
|
|
||||||
-v format="$REC_FORMAT" \
|
|
||||||
-v format_local="$FORMAT_LOCAL" \
|
|
||||||
"$AWK_RECORDINGS"
|
|
||||||
)"
|
|
||||||
mb_release "$1" |
|
mb_release "$1" |
|
||||||
$JQ \
|
$JQ \
|
||||||
--arg rid "$1" \
|
--arg rid "$1" \
|
||||||
@@ -179,16 +70,7 @@ list_recordings() {
|
|||||||
$deco
|
$deco
|
||||||
] |
|
] |
|
||||||
join("\t")' |
|
join("\t")' |
|
||||||
awk \
|
awk_recordings "${rectmp:-}"
|
||||||
-F "\t" \
|
|
||||||
-v file_local_recordings="${rectmp:-}" \
|
|
||||||
-v format="$REC_FORMAT" \
|
|
||||||
-v format_local="$FORMAT_LOCAL" \
|
|
||||||
"$AWK_RECORDINGS" |
|
|
||||||
sort -k1,1n -k2,2g |
|
|
||||||
cut -d "$(printf '\t')" -f 2- |
|
|
||||||
column -t -s "$(printf '\t')" -R 3,4,7 |
|
|
||||||
sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\):\(.*$\)$|\t\1\t\2\t\3|'
|
|
||||||
if [ "${rectmp:-}" ] && [ -f "$rectmp" ]; then
|
if [ "${rectmp:-}" ] && [ -f "$rectmp" ]; then
|
||||||
rm -f "$rectmp"
|
rm -f "$rectmp"
|
||||||
fi
|
fi
|
||||||
@@ -210,44 +92,31 @@ list_local_releasegroups() {
|
|||||||
list_artists_from_json() {
|
list_artists_from_json() {
|
||||||
cat |
|
cat |
|
||||||
$JQ 'map([.artist.id, .artist.type, .name] | join("\t")) | join("\n")' |
|
$JQ 'map([.artist.id, .artist.type, .name] | join("\t")) | join("\n")' |
|
||||||
awk \
|
awk_artists "$SORT_NO"
|
||||||
-F "\t" \
|
|
||||||
-v file_local_artists="${LOCALDATA_ARTISTS:-}" \
|
|
||||||
-v format_person="$AV_PERSON" \
|
|
||||||
-v format_group="$AV_GROUP" \
|
|
||||||
-v format_disambiguation="$AV_DISAMBIGUATION" \
|
|
||||||
-v format_local="$FORMAT_LOCAL" \
|
|
||||||
"$AWK_ARTISTS" |
|
|
||||||
column -t -s "$(printf '\t')" -l 2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Print playlist currently loaded
|
# Print playlist currently loaded
|
||||||
list_playlist() {
|
list_playlist() {
|
||||||
count=$(mpv_playlist_count)
|
count=$(mpv_playlist_count)
|
||||||
|
[ "$count" ] || return 0
|
||||||
[ "$count" -eq 0 ] && return 0
|
[ "$count" -eq 0 ] && return 0
|
||||||
mpvquery=""
|
mpvquery=""
|
||||||
for i in $(seq 0 $((count - 1))); do
|
for i in $(seq 0 $((count - 1))); do
|
||||||
mpvquery="$mpvquery\${playlist/$i/current}\t\${playlist/$i/title}\n"
|
mpvquery="$mpvquery\${playlist/$i/title}\t\${playlist/$i/current}\n"
|
||||||
done
|
done
|
||||||
mpvtmp=$(mktemp)
|
__mpv_get "$mpvquery" | grep '.' | awk_playlist
|
||||||
# Get playlist information from mpv
|
}
|
||||||
__mpv_get "$mpvquery" | grep '.' >"$mpvtmp"
|
|
||||||
# Get MusicBrainz Track ID of current recording
|
# List stored playlist
|
||||||
current_id=$(grep "^yes" "$mpvtmp" | cut -d "$(printf '\t')" -f 3)
|
#
|
||||||
# Get file to be used in file_local_recordings
|
# @argument $1: paylist name
|
||||||
rectmp=$(mktemp)
|
list_playlist_stored() {
|
||||||
cut -d "$(printf '\t')" -f 3 "$mpvtmp" >"$rectmp"
|
t=$(mktemp)
|
||||||
# Get list
|
r=$(mktemp)
|
||||||
cut -d "$(printf '\t')" -f 2- "$mpvtmp" |
|
generate_playlist_stored "$PLAYLIST_DIRECTORY/$1" |
|
||||||
awk \
|
grep "$(printf '\t')" |
|
||||||
-F "\t" \
|
cut -d "," -f 2- >"$t"
|
||||||
-v file_local_recordings="${rectmp:-}" \
|
grep -v "/dev/null$" "$t" | cut -d "$(printf '\t')" -f 2 >"$r"
|
||||||
-v format="$REC_FORMAT_NO_NUMBER" \
|
awk_recordings "$r" <"$t"
|
||||||
-v format_current="$FORMAT_CURRENT" \
|
rm -f "$t" "$r"
|
||||||
-v current_id="$current_id" \
|
|
||||||
"$AWK_RECORDINGS" |
|
|
||||||
cut -d "$(printf '\t')" -f 2- |
|
|
||||||
column -t -s "$(printf '\t')" -R 5 |
|
|
||||||
sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\):\(.*$\)$|\t\1\t\2\t\3|'
|
|
||||||
rm -f "$rectmp" "$mpvtmp"
|
|
||||||
}
|
}
|
||||||
|
|||||||
152
src/sh/local.sh
152
src/sh/local.sh
@@ -4,7 +4,7 @@
|
|||||||
# will also use the methods here, and modifications thereof, to support
|
# will also use the methods here, and modifications thereof, to support
|
||||||
# MusicBainz collections.
|
# MusicBainz collections.
|
||||||
if [ ! "${LOCAL_LOADED:-}" ]; then
|
if [ ! "${LOCAL_LOADED:-}" ]; then
|
||||||
LOCALDATADIR="$HOME/.cache/$APP_NAME/local"
|
LOCALDATADIR="${XDG_DATA_HOME:-"$HOME/.local/share"}/$APP_NAME"
|
||||||
LOCALDATA_ARTISTS="$LOCALDATADIR/artists"
|
LOCALDATA_ARTISTS="$LOCALDATADIR/artists"
|
||||||
LOCALDATA_RELEASEGROUPS="$LOCALDATADIR/releasegroups"
|
LOCALDATA_RELEASEGROUPS="$LOCALDATADIR/releasegroups"
|
||||||
LOCALDATA_RELEASES="$LOCALDATADIR/releases"
|
LOCALDATA_RELEASES="$LOCALDATADIR/releases"
|
||||||
@@ -16,6 +16,15 @@ if [ ! "${LOCAL_LOADED:-}" ]; then
|
|||||||
LOCALDATA_RELEASES_LIST="$LOCALDATADIR/releases_list"
|
LOCALDATA_RELEASES_LIST="$LOCALDATADIR/releases_list"
|
||||||
DECORATION_FILENAME=${DECORATION_FILENAME:-"mbid.json"}
|
DECORATION_FILENAME=${DECORATION_FILENAME:-"mbid.json"}
|
||||||
|
|
||||||
|
# Create necessary files
|
||||||
|
[ -d "$LOCALDATADIR" ] || mkdir -p "$LOCALDATADIR"
|
||||||
|
[ -f "$LOCALDATA_ARTISTS" ] || touch "$LOCALDATA_ARTISTS"
|
||||||
|
[ -f "$LOCALDATA_RELEASEGROUPS" ] || touch "$LOCALDATA_RELEASEGROUPS"
|
||||||
|
[ -f "$LOCALDATA_RELEASES" ] || touch "$LOCALDATA_RELEASES"
|
||||||
|
[ -f "$LOCALDATA_ARTISTS_LIST" ] || touch "$LOCALDATA_ARTISTS_LIST"
|
||||||
|
[ -f "$LOCALDATA_RELEASEGROUPS_LIST" ] || touch "$LOCALDATA_RELEASEGROUPS_LIST"
|
||||||
|
[ -f "$LOCALDATA_RELEASES_LIST" ] || touch "$LOCALDATA_RELEASES_LIST"
|
||||||
|
|
||||||
export LOCALDATADIR LOCALDATA_ARTISTS LOCALDATA_RELEASEGROUPS \
|
export LOCALDATADIR LOCALDATA_ARTISTS LOCALDATA_RELEASEGROUPS \
|
||||||
LOCALDATA_RELEASES LOCALDATA_ARTISTS_VIEW LOCALDATA_RELEASEGROUPS_VIEW \
|
LOCALDATA_RELEASES LOCALDATA_ARTISTS_VIEW LOCALDATA_RELEASEGROUPS_VIEW \
|
||||||
LOCALDATA_RELEASES_VIEW LOCALDATA_ARTISTS_LIST LOCALDATA_RELEASEGROUPS_LIST \
|
LOCALDATA_RELEASES_VIEW LOCALDATA_ARTISTS_LIST LOCALDATA_RELEASEGROUPS_LIST \
|
||||||
@@ -148,7 +157,7 @@ END { for (i in id) print title[i], id[i], fname[i] }
|
|||||||
' "$tmpj" "$tmpf" >"$assocfile"
|
' "$tmpj" "$tmpf" >"$assocfile"
|
||||||
rm -f "$tmpj" "$tmpf"
|
rm -f "$tmpj" "$tmpf"
|
||||||
# Ask user if this is ok
|
# Ask user if this is ok
|
||||||
info "We discovered the following associatoin:"
|
info "We discovered the following association:"
|
||||||
while IFS= read -r line; do
|
while IFS= read -r line; do
|
||||||
t="$(echo "$line" | cut -d "$(printf '\t')" -f 1)"
|
t="$(echo "$line" | cut -d "$(printf '\t')" -f 1)"
|
||||||
f="$(echo "$line" | cut -d "$(printf '\t')" -f 3)"
|
f="$(echo "$line" | cut -d "$(printf '\t')" -f 3)"
|
||||||
@@ -174,44 +183,6 @@ END { for (i in id) print title[i], id[i], fname[i] }
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# Load missing cache entries (batch mode)
|
|
||||||
#
|
|
||||||
# argument $1: type
|
|
||||||
#
|
|
||||||
# This method reads one MusicBrainz IDs of the specified type from stdin (one
|
|
||||||
# per line), and fetches the missing items.
|
|
||||||
__batch_load_missing() {
|
|
||||||
tmpf=$(mktemp)
|
|
||||||
cat |
|
|
||||||
cache_get_file_batch "$1" |
|
|
||||||
xargs \
|
|
||||||
sh -c 'for f; do [ -e "$f" ] || echo "$f"; done' _ |
|
|
||||||
cache_mbid_from_path_batch >"$tmpf"
|
|
||||||
lines=$(wc -l "$tmpf" | cut -d ' ' -f 1)
|
|
||||||
if [ "$lines" -gt 0 ]; then
|
|
||||||
case "$1" in
|
|
||||||
"$TYPE_ARTIST") tt="artists" ;;
|
|
||||||
"$TYPE_RELEASEGROUP") tt="release groups" ;;
|
|
||||||
"$TYPE_RELEASE") tt="releases" ;;
|
|
||||||
esac
|
|
||||||
info "Fetching missing $tt"
|
|
||||||
cnt=0
|
|
||||||
while IFS= read -r mbid; do
|
|
||||||
case "$1" in
|
|
||||||
"$TYPE_ARTIST")
|
|
||||||
name=$(mb_artist "$mbid" | $JQ '.name')
|
|
||||||
;;
|
|
||||||
"$TYPE_RELEASEGROUP") name=$(mb_releasegroup "$mbid" | $JQ '.title') ;;
|
|
||||||
"$TYPE_RELEASE") name=$(mb_release "$mbid" | $JQ '.title') ;;
|
|
||||||
esac
|
|
||||||
cnt=$((cnt + 1))
|
|
||||||
info "$(printf "%d/%d (%s: %s)" "$cnt" "$lines" "$mbid" "$name")"
|
|
||||||
sleep 1
|
|
||||||
done <"$tmpf"
|
|
||||||
fi
|
|
||||||
rm -f "$tmpf"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Precompute lists
|
# Precompute lists
|
||||||
#
|
#
|
||||||
# The main views (VIEW_ARTIST and TYPE_RELEASEGROUP) for locally available
|
# The main views (VIEW_ARTIST and TYPE_RELEASEGROUP) for locally available
|
||||||
@@ -220,16 +191,17 @@ __batch_load_missing() {
|
|||||||
# theme-independent fashion. The lists are stored in the files
|
# theme-independent fashion. The lists are stored in the files
|
||||||
# `LOCALDATA_ARTISTS_LIST` and `LOCALDATA_RELEASEGROUPS_LIST`.
|
# `LOCALDATA_ARTISTS_LIST` and `LOCALDATA_RELEASEGROUPS_LIST`.
|
||||||
__precompute_lists() {
|
__precompute_lists() {
|
||||||
cache_get_file_batch "$TYPE_ARTIST" <"$LOCALDATA_ARTISTS" | xargs \
|
cache_get_file_batch "$TYPE_ARTIST" <"$LOCALDATA_ARTISTS" | xargs -d "\n" \
|
||||||
$JQ '[
|
$JQ '[
|
||||||
.id,
|
.id,
|
||||||
.type,
|
.type,
|
||||||
.name,
|
.name,
|
||||||
|
."sort-name",
|
||||||
.disambiguation,
|
.disambiguation,
|
||||||
.["life-span"].begin,
|
.["life-span"].begin,
|
||||||
.["life-span"].end
|
.["life-span"].end
|
||||||
] | join("\t")' >"$LOCALDATA_ARTISTS_LIST"
|
] | join("\t")' >"$LOCALDATA_ARTISTS_LIST" &
|
||||||
cache_get_file_batch "$TYPE_RELEASEGROUP" <"$LOCALDATA_RELEASEGROUPS" | xargs \
|
cache_get_file_batch "$TYPE_RELEASEGROUP" <"$LOCALDATA_RELEASEGROUPS" | xargs -d "\n" \
|
||||||
$JQ '[
|
$JQ '[
|
||||||
.id,
|
.id,
|
||||||
."primary-type",
|
."primary-type",
|
||||||
@@ -237,7 +209,8 @@ __precompute_lists() {
|
|||||||
."first-release-date",
|
."first-release-date",
|
||||||
.title,
|
.title,
|
||||||
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
|
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
|
||||||
] | join("\t")' >"$LOCALDATA_RELEASEGROUPS_LIST"
|
] | join("\t")' >"$LOCALDATA_RELEASEGROUPS_LIST" &
|
||||||
|
wait
|
||||||
}
|
}
|
||||||
|
|
||||||
# Precompute views
|
# Precompute views
|
||||||
@@ -246,49 +219,8 @@ __precompute_lists() {
|
|||||||
# The resulting views are stored in the files `LOCALDATA_ARTISTS_VIEW` and
|
# The resulting views are stored in the files `LOCALDATA_ARTISTS_VIEW` and
|
||||||
# `LOCALDATA_RELEASEGROUPS_VIEW`.
|
# `LOCALDATA_RELEASEGROUPS_VIEW`.
|
||||||
precompute_views() {
|
precompute_views() {
|
||||||
awk \
|
awk_artists "$SORT_ARTIST_DEFAULT" <"$LOCALDATA_ARTISTS_LIST" >"$LOCALDATA_ARTISTS_VIEW"
|
||||||
-F "\t" \
|
awk_releasegroups "$SORT_RG_DEFAULT" <"$LOCALDATA_RELEASEGROUPS_LIST" >"$LOCALDATA_RELEASEGROUPS_VIEW"
|
||||||
-v file_local_artists="${LOCALDATA_ARTISTS:-}" \
|
|
||||||
-v format_person="$AV_PERSON" \
|
|
||||||
-v format_group="$AV_GROUP" \
|
|
||||||
-v format_disambiguation="$AV_DISAMBIGUATION" \
|
|
||||||
-v format_local="$FORMAT_LOCAL" \
|
|
||||||
"$AWK_ARTISTS" "$LOCALDATA_ARTISTS_LIST" |
|
|
||||||
sort |
|
|
||||||
column -t -s "$(printf '\t')" -l 2 >"$LOCALDATA_ARTISTS_VIEW"
|
|
||||||
#column -t -s "$(printf '\t')" |
|
|
||||||
#sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\)$|\t\1\t\2|' >"$LOCALDATA_ARTISTS_VIEW"
|
|
||||||
awk \
|
|
||||||
-F "\t" \
|
|
||||||
-v file_local_releasegroups="${LOCALDATA_RELEASEGROUPS:-}" \
|
|
||||||
-v format_release="$RGV_RELEASE" \
|
|
||||||
-v format_release_w_artist="$RGV_RELEASE_W_ARTIST" \
|
|
||||||
-v format_year="$RGV_YEAR" \
|
|
||||||
-v format_album="$FORMAT_TYPE_ALBUM" \
|
|
||||||
-v format_single="$FORMAT_TYPE_SINGLE" \
|
|
||||||
-v format_ep="$FORMAT_TYPE_EP" \
|
|
||||||
-v format_broadcast="$FORMAT_TYPE_BROADCAST" \
|
|
||||||
-v format_other="$FORMAT_TYPE_OTHER" \
|
|
||||||
-v format_has_secondary="$FORMAT_TYPE_HAS_SECONDARY" \
|
|
||||||
-v format_secondary="$FORMAT_TYPE_SECONDARY" \
|
|
||||||
-v format_compilation="$FORMAT_TYPE_SECONDARY_COMPILATION" \
|
|
||||||
-v format_soundtrack="$FORMAT_TYPE_SECONDARY_SOUNDTRACK" \
|
|
||||||
-v format_spokenword="$FORMAT_TYPE_SECONDARY_SPOKENWORD" \
|
|
||||||
-v format_interview="$FORMAT_TYPE_SECONDARY_INTERVIEW" \
|
|
||||||
-v format_audiobook="$FORMAT_TYPE_SECONDARY_AUDIOBOOK" \
|
|
||||||
-v format_audiodrama="$FORMAT_TYPE_SECONDARY_AUDIODRAMA" \
|
|
||||||
-v format_live="$FORMAT_TYPE_SECONDARY_LIVE" \
|
|
||||||
-v format_remix="$FORMAT_TYPE_SECONDARY_REMIX" \
|
|
||||||
-v format_djmix="$FORMAT_TYPE_SECONDARY_DJMIX" \
|
|
||||||
-v format_mixtape="$FORMAT_TYPE_SECONDARY_MIXTAPE" \
|
|
||||||
-v format_demo="$FORMAT_TYPE_SECONDARY_DEMO" \
|
|
||||||
-v format_fieldrec="$FORMAT_TYPE_SECONDARY_FIELDREC" \
|
|
||||||
-v format_local="$FORMAT_LOCAL" \
|
|
||||||
"$AWK_RELEASEGROUPS" "$LOCALDATA_RELEASEGROUPS_LIST" | sort -n -r |
|
|
||||||
cut -d "$(printf '\t')" -f 2- |
|
|
||||||
column -t -s "$(printf '\t')" -l 5 >"$LOCALDATA_RELEASEGROUPS_VIEW"
|
|
||||||
#column -t -s "$(printf '\t')" |
|
|
||||||
#sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\)$|\t\1\t\2|' >"$LOCALDATA_RELEASEGROUPS_VIEW"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Load local music
|
# Load local music
|
||||||
@@ -308,24 +240,29 @@ reloaddb() {
|
|||||||
tmpreleases=$(mktemp)
|
tmpreleases=$(mktemp)
|
||||||
cut -d "$(printf '\t')" -f 1 "$LOCALDATA_RELEASES" |
|
cut -d "$(printf '\t')" -f 1 "$LOCALDATA_RELEASES" |
|
||||||
tee "$tmpreleases" |
|
tee "$tmpreleases" |
|
||||||
__batch_load_missing "$TYPE_RELEASE"
|
batch_load_missing "$TYPE_RELEASE"
|
||||||
tmpreleasefiles=$(mktemp)
|
tmpreleasefiles=$(mktemp)
|
||||||
cache_get_file_batch "$TYPE_RELEASE" <"$tmpreleases" >"$tmpreleasefiles"
|
cache_get_file_batch "$TYPE_RELEASE" <"$tmpreleases" >"$tmpreleasefiles"
|
||||||
xargs \
|
(
|
||||||
$JQ '."release-group".id' \
|
xargs -d "\n" \
|
||||||
<"$tmpreleasefiles" >"$LOCALDATA_RELEASEGROUPS"
|
$JQ '."release-group".id' \
|
||||||
xargs \
|
<"$tmpreleasefiles" >"$LOCALDATA_RELEASEGROUPS"
|
||||||
$JQ '."release-group"."artist-credit" | map(.artist.id) | join("\n")' \
|
tf1=$(mktemp)
|
||||||
<"$tmpreleasefiles" >"$LOCALDATA_ARTISTS"
|
sort "$LOCALDATA_RELEASEGROUPS" | uniq >"$tf1"
|
||||||
|
mv "$tf1" "$LOCALDATA_RELEASEGROUPS"
|
||||||
|
) &
|
||||||
|
(
|
||||||
|
xargs -d "\n" \
|
||||||
|
$JQ '."release-group"."artist-credit" | map(.artist.id) | join("\n")' \
|
||||||
|
<"$tmpreleasefiles" >"$LOCALDATA_ARTISTS"
|
||||||
|
tf2=$(mktemp)
|
||||||
|
sort "$LOCALDATA_ARTISTS" | uniq >"$tf2"
|
||||||
|
mv "$tf2" "$LOCALDATA_ARTISTS"
|
||||||
|
) &
|
||||||
|
wait
|
||||||
rm -f "$tmpreleases" "$tmpreleasefiles"
|
rm -f "$tmpreleases" "$tmpreleasefiles"
|
||||||
tf1=$(mktemp)
|
batch_load_missing "$TYPE_RELEASEGROUP" <"$LOCALDATA_RELEASEGROUPS"
|
||||||
tf2=$(mktemp)
|
batch_load_missing "$TYPE_ARTIST" <"$LOCALDATA_ARTISTS"
|
||||||
sort "$LOCALDATA_RELEASEGROUPS" | uniq >"$tf1"
|
|
||||||
mv "$tf1" "$LOCALDATA_RELEASEGROUPS"
|
|
||||||
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
|
__precompute_lists
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,10 +273,8 @@ reloaddb() {
|
|||||||
# derivation of the MusicBrainz artist IDs and MusicBrainz release-group IDs
|
# derivation of the MusicBrainz artist IDs and MusicBrainz release-group IDs
|
||||||
# from the MusicBrainz releases (see the `reloaddb` method above).
|
# from the MusicBrainz releases (see the `reloaddb` method above).
|
||||||
local_files_present() {
|
local_files_present() {
|
||||||
cache_get_file_batch "$TYPE_ARTIST" <"$LOCALDATA_ARTISTS" | xargs ls >/dev/null 2>&1 || return 1
|
cached "$TYPE_ARTIST" "$LOCALDATA_ARTISTS" || return 1
|
||||||
cache_get_file_batch "$TYPE_RELEASEGROUP" <"$LOCALDATA_RELEASEGROUPS" | xargs ls >/dev/null 2>&1 || return 1
|
cached "$TYPE_RELEASEGROUP" "$LOCALDATA_RELEASEGROUPS" || return 1
|
||||||
#cut -d "$(printf '\t')" -f 1 "$LOCALDATA_RELEASES" | cache_get_file_batch "$TYPE_RELEASE" | xargs ls >/dev/null 2>&1 || return 1
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Load missing files
|
# Load missing files
|
||||||
@@ -347,7 +282,6 @@ local_files_present() {
|
|||||||
# If missing files were detected with `local_files_present`, then these missing
|
# If missing files were detected with `local_files_present`, then these missing
|
||||||
# files may be cached using the present method.
|
# files may be cached using the present method.
|
||||||
load_missing_files() {
|
load_missing_files() {
|
||||||
__batch_load_missing "$TYPE_ARTIST" <"$LOCALDATA_ARTISTS"
|
batch_load_missing "$TYPE_ARTIST" <"$LOCALDATA_ARTISTS"
|
||||||
__batch_load_missing "$TYPE_RELEASEGROUP" <"$LOCALDATA_RELEASEGROUPS"
|
batch_load_missing "$TYPE_RELEASEGROUP" <"$LOCALDATA_RELEASEGROUPS"
|
||||||
#cut -d "$(printf '\t')" -f 1 "$LOCALDATA_RELEASES" | __batch_load_missing "$TYPE_RELEASE"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ if [ ! "${LOG_LOADED:-}" ]; then
|
|||||||
ERR="\033[38;5;196m"
|
ERR="\033[38;5;196m"
|
||||||
INFO="\033[38;5;75m"
|
INFO="\033[38;5;75m"
|
||||||
OFF="\033[m"
|
OFF="\033[m"
|
||||||
LOGDIR="$HOME/.local/state/$APP_NAME"
|
LOGDIR="${XDG_STATE_HOME:-"$HOME/.local/state"}/$APP_NAME"
|
||||||
[ -d "$LOGDIR" ] || mkdir -p "$LOGDIR"
|
[ -d "$LOGDIR" ] || mkdir -p "$LOGDIR"
|
||||||
LOGFILE="$LOGDIR/log"
|
LOGFILE="$LOGDIR/log"
|
||||||
export ERR INFO OFF LOGFILE
|
export ERR INFO OFF LOGFILE
|
||||||
|
|||||||
121
src/sh/lyrics.sh
Normal file
121
src/sh/lyrics.sh
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
# Methods and constants for lyrics handling
|
||||||
|
#
|
||||||
|
# Lyrics are retrieved as following:
|
||||||
|
# 1. Check if the lyrics are already stored in this store
|
||||||
|
# 2. If the track is playable, check if an accompanying `.lrc` file is present.
|
||||||
|
# 3. If the track is playable, read lyrics from the tags
|
||||||
|
# 4. Call custom fetch command
|
||||||
|
#
|
||||||
|
# The path to the lyrics is `__radix(mbid)/mbid.lrc` where `mbid` is the
|
||||||
|
# MusicBrainz ID of the track.
|
||||||
|
|
||||||
|
if [ ! "${LYRICS_LOADED:-}" ]; then
|
||||||
|
# Folder to store lyrics
|
||||||
|
LYRICS_DIRECTORY="${LYRICS_DIRECTORY:-"$LOCALDATADIR/lyrics"}"
|
||||||
|
[ -d "$LYRICS_DIRECTORY" ] || mkdir -p "$LYRICS_DIRECTORY"
|
||||||
|
export LYRICS_DIRECTORY
|
||||||
|
|
||||||
|
# Custom command to fetch lyrics
|
||||||
|
#
|
||||||
|
# This command reads from stdin the json object of the release and prints the
|
||||||
|
# lyrics of the track.
|
||||||
|
LYRICS_FETCH_CUSTOM="${LYRICS_FETCH_CUSTOM:-""}"
|
||||||
|
export LYRICS_FETCH_CUSTOM
|
||||||
|
|
||||||
|
export LYRICS_LOADED=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# File path for lyrics file
|
||||||
|
#
|
||||||
|
# @argument $1: MusicBrainz track ID
|
||||||
|
lyrics_file() {
|
||||||
|
mbid="${1:-}"
|
||||||
|
echo "$LYRICS_DIRECTORY/$(__radix "$mbid").lrc"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Store lyrics
|
||||||
|
#
|
||||||
|
# @argument $1: MusicBrainz track ID
|
||||||
|
#
|
||||||
|
# This methods reads from stdin and stores it.
|
||||||
|
store_lyrics() {
|
||||||
|
mbid="${1:-}"
|
||||||
|
file="$(lyrics_file "$mbid")"
|
||||||
|
dir="$(dirname "$file")"
|
||||||
|
[ -d "$dir" ] || mkdir -p "$dir"
|
||||||
|
cat >"$file"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fetch lyrics using custom command and store them
|
||||||
|
#
|
||||||
|
# @argument $1: MusicBrainz release ID
|
||||||
|
# @argument $2: MusicBrainz track ID
|
||||||
|
#
|
||||||
|
# The custom script is executed only if the environment variable is set. Else
|
||||||
|
# the message stored in `$LYRICS_NO_LYRICS` is saved.
|
||||||
|
store_lyrics_custom() {
|
||||||
|
rlid="${1:-}"
|
||||||
|
mbid="${2:-}"
|
||||||
|
if [ "$LYRICS_FETCH_CUSTOM" ]; then
|
||||||
|
mb_release "$rlid" |
|
||||||
|
$JQ --arg mbid "$mbid" '{release: ., trackid: $mbid}' |
|
||||||
|
sh -c "$LYRICS_FETCH_CUSTOM" |
|
||||||
|
store_lyrics "$mbid"
|
||||||
|
else
|
||||||
|
echo "$LYRICS_NO_LYRICS" |
|
||||||
|
store_lyrics "$mbid"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Print lyrics
|
||||||
|
#
|
||||||
|
# @argument $1: MusicBrainz release ID
|
||||||
|
# @argument $2: MusicBrainz track ID
|
||||||
|
lyrics() {
|
||||||
|
rlid="${1:-}"
|
||||||
|
mbid="${2:-}"
|
||||||
|
# 1. Check if lyrics has already been stored
|
||||||
|
file="$(lyrics_file "$mbid")"
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
cat "$file"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
# 2. & 3.: For playable tracks only
|
||||||
|
decoration="$(grep "^$rlid" "$LOCALDATA_RELEASES" | cut -d "$(printf '\t')" -f 2)"
|
||||||
|
if [ "$decoration" ] && [ -f "$decoration" ]; then
|
||||||
|
afname="$($JQ --arg mbid "$mbid" '.tracks | to_entries[] | select(.key == $mbid) | .value' "$decoration")"
|
||||||
|
af="$(dirname "$decoration")/$afname"
|
||||||
|
# Check if `.lrc` file exists
|
||||||
|
lf="$(echo "$af" | rev | cut -d "." -f 2- | rev).lrc"
|
||||||
|
if [ -f "$lf" ]; then
|
||||||
|
store_lyrics "$mbid" <"$lf"
|
||||||
|
cat "$file"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
# Read lyrics from tag
|
||||||
|
if [ "$FFPROBE" ]; then
|
||||||
|
lyrics="$($FFPROBE -v error -show_entries format_tags -print_format json "$af" |
|
||||||
|
$JQ '.format.tags | ."USLT:description" // ."LYRICS" // ."Lyrics" // ."©lyr" // ."WM/Lyrics" // ""')"
|
||||||
|
if [ "$lyrics" ]; then
|
||||||
|
echo "$lyrics" | store_lyrics "$mbid"
|
||||||
|
cat "$file"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
# Make call to external command
|
||||||
|
store_lyrics_custom "$rlid" "$mbid"
|
||||||
|
cat "$file"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Reload lyrics file
|
||||||
|
#
|
||||||
|
# @argument $1: MusicBrainz release ID
|
||||||
|
# @argument $2: MusicBrainz track ID
|
||||||
|
reload_lyrics() {
|
||||||
|
rlid="${1:-}"
|
||||||
|
mbid="${2:-}"
|
||||||
|
file="$(lyrics_file "$mbid")"
|
||||||
|
rm -f "$file"
|
||||||
|
lyrics "$rlid" "$mbid"
|
||||||
|
}
|
||||||
50
src/sh/mb.sh
50
src/sh/mb.sh
@@ -180,8 +180,7 @@ mb_results_async() {
|
|||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
# Show results
|
# Show results
|
||||||
column -t -s "$(printf '\t')" "$RESULTS" |
|
cat "$RESULTS" || true
|
||||||
sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\)$|\t\1\t\2|'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Initiate search on MusicBrainz
|
# Initiate search on MusicBrainz
|
||||||
@@ -200,8 +199,12 @@ mb_search_async() {
|
|||||||
rm -f "$PIDFILE"
|
rm -f "$PIDFILE"
|
||||||
kill -9 "$pid" >/dev/null 2>&1 || true
|
kill -9 "$pid" >/dev/null 2>&1 || true
|
||||||
fi
|
fi
|
||||||
# Stop, if no search string is given
|
# Clear search and stop if no search string is given
|
||||||
[ "$FZF_QUERY" ] || exit 0
|
if [ ! "$FZF_QUERY" ]; then
|
||||||
|
rm -f "$RESULTS"
|
||||||
|
touch "$RESULTS"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
# Store PID of current process
|
# Store PID of current process
|
||||||
echo "$$" >"$PIDFILE"
|
echo "$$" >"$PIDFILE"
|
||||||
touch "$LOCKFILE"
|
touch "$LOCKFILE"
|
||||||
@@ -212,18 +215,12 @@ mb_search_async() {
|
|||||||
.id,
|
.id,
|
||||||
.type,
|
.type,
|
||||||
.name,
|
.name,
|
||||||
|
."sort-name",
|
||||||
.disambiguation,
|
.disambiguation,
|
||||||
.["life-span"].begin,
|
.["life-span"].begin,
|
||||||
.["life-span"].end
|
.["life-span"].end
|
||||||
] | join("\t")' |
|
] | join("\t")' |
|
||||||
awk \
|
awk_artists "$SORT_NO" >"$RESULTS" ||
|
||||||
-F "\t" \
|
|
||||||
-v file_local_artists="${LOCALDATA_ARTISTS:-}" \
|
|
||||||
-v format_person="$AV_PERSON" \
|
|
||||||
-v format_group="$AV_GROUP" \
|
|
||||||
-v format_disambiguation="$AV_DISAMBIGUATION" \
|
|
||||||
-v format_local="$FORMAT_LOCAL" \
|
|
||||||
"$AWK_ARTISTS" >"$RESULTS" ||
|
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
api_mb_search_releasegroup "$FZF_QUERY" |
|
api_mb_search_releasegroup "$FZF_QUERY" |
|
||||||
@@ -235,34 +232,7 @@ mb_search_async() {
|
|||||||
.title,
|
.title,
|
||||||
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
|
(."artist-credit" | map(([.name, .joinphrase]|join(""))) | join(""))
|
||||||
] | join("\t")' |
|
] | join("\t")' |
|
||||||
awk \
|
awk_releasegroups "$SORT_NO" >"$RESULTS" ||
|
||||||
-F "\t" \
|
|
||||||
-v file_local_releasegroups="${LOCALDATA_RELEASEGROUPS:-}" \
|
|
||||||
-v format_release="$RGV_RELEASE" \
|
|
||||||
-v format_release_w_artist="$RGV_RELEASE_W_ARTIST" \
|
|
||||||
-v format_year="$RGV_YEAR" \
|
|
||||||
-v format_album="$FORMAT_TYPE_ALBUM" \
|
|
||||||
-v format_single="$FORMAT_TYPE_SINGLE" \
|
|
||||||
-v format_ep="$FORMAT_TYPE_EP" \
|
|
||||||
-v format_broadcast="$FORMAT_TYPE_BROADCAST" \
|
|
||||||
-v format_other="$FORMAT_TYPE_OTHER" \
|
|
||||||
-v format_has_secondary="$FORMAT_TYPE_HAS_SECONDARY" \
|
|
||||||
-v format_secondary="$FORMAT_TYPE_SECONDARY" \
|
|
||||||
-v format_compilation="$FORMAT_TYPE_SECONDARY_COMPILATION" \
|
|
||||||
-v format_soundtrack="$FORMAT_TYPE_SECONDARY_SOUNDTRACK" \
|
|
||||||
-v format_spokenword="$FORMAT_TYPE_SECONDARY_SPOKENWORD" \
|
|
||||||
-v format_interview="$FORMAT_TYPE_SECONDARY_INTERVIEW" \
|
|
||||||
-v format_audiobook="$FORMAT_TYPE_SECONDARY_AUDIOBOOK" \
|
|
||||||
-v format_audiodrama="$FORMAT_TYPE_SECONDARY_AUDIODRAMA" \
|
|
||||||
-v format_live="$FORMAT_TYPE_SECONDARY_LIVE" \
|
|
||||||
-v format_remix="$FORMAT_TYPE_SECONDARY_REMIX" \
|
|
||||||
-v format_djmix="$FORMAT_TYPE_SECONDARY_DJMIX" \
|
|
||||||
-v format_mixtape="$FORMAT_TYPE_SECONDARY_MIXTAPE" \
|
|
||||||
-v format_demo="$FORMAT_TYPE_SECONDARY_DEMO" \
|
|
||||||
-v format_fieldrec="$FORMAT_TYPE_SECONDARY_FIELDREC" \
|
|
||||||
-v format_local="$FORMAT_LOCAL" \
|
|
||||||
"$AWK_RELEASEGROUPS" |
|
|
||||||
cut -d "$(printf '\t')" -f 2- >"$RESULTS" ||
|
|
||||||
true
|
true
|
||||||
fi
|
fi
|
||||||
# Process ends now: Display and quit
|
# Process ends now: Display and quit
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ mpv_playlist_position() {
|
|||||||
# Moves the track at the first index to the position of the track of the second
|
# Moves the track at the first index to the position of the track of the second
|
||||||
# index. Also here, indices are 0 based.
|
# index. Also here, indices are 0 based.
|
||||||
mpv_playlist_move() {
|
mpv_playlist_move() {
|
||||||
__mpv_command_with_args2 "playlist-move" "$1" "$2" >>/tmp/foo
|
__mpv_command_with_args2 "playlist-move" "$1" "$2"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Remove all tracks from the playlist
|
# Remove all tracks from the playlist
|
||||||
|
|||||||
@@ -43,51 +43,6 @@ __playback_cmd_from_key() {
|
|||||||
case ",$KEYS_N_SEEK_BACKWARD," in *",$key,"*) echo "$PLAYBACK_CMD_SEEK_BACKWARD" && return ;; esac
|
case ",$KEYS_N_SEEK_BACKWARD," in *",$key,"*) echo "$PLAYBACK_CMD_SEEK_BACKWARD" && return ;; esac
|
||||||
}
|
}
|
||||||
|
|
||||||
# Generate playlist from MB release ID and path to decoration
|
|
||||||
#
|
|
||||||
# @argument $1: MusicBrainz release ID
|
|
||||||
# @argument $2: Path to decoration file
|
|
||||||
# @argument $3: MusicBrainz track ID to select (optional)
|
|
||||||
__generate_playlist() {
|
|
||||||
printf "#EXTM3U\n"
|
|
||||||
dir="$(dirname "$2")"
|
|
||||||
mb_release "$1" |
|
|
||||||
$JQ \
|
|
||||||
--slurpfile decofile "$2" \
|
|
||||||
--arg base "$dir" \
|
|
||||||
--arg deco "$2" \
|
|
||||||
--arg tid "${3:-}" \
|
|
||||||
'$decofile[].tracks as $filenames |
|
|
||||||
. |
|
|
||||||
.id as $rid |
|
|
||||||
.media |
|
|
||||||
length as $l |
|
|
||||||
.[] |
|
|
||||||
.position as $pos |
|
|
||||||
.tracks |
|
|
||||||
if ($tid == "") then . else map(select(.id == $tid)) end |
|
|
||||||
map({
|
|
||||||
t: [
|
|
||||||
$rid,
|
|
||||||
.id,
|
|
||||||
$l,
|
|
||||||
$pos,
|
|
||||||
.number,
|
|
||||||
.length,
|
|
||||||
.title,
|
|
||||||
(."artist-credit" | map([.name, .joinphrase] | join("")) | join("")),
|
|
||||||
$deco
|
|
||||||
] | join("\t"),
|
|
||||||
length: (.length // 0 / 1000 | round | tostring),
|
|
||||||
$pos,
|
|
||||||
number: .number,
|
|
||||||
file: $filenames[.id]
|
|
||||||
}) |
|
|
||||||
map(if(.number | type == "string" and test("^[0-9]+$")) then .number |= tonumber else . end) |
|
|
||||||
sort_by([.pos, .number]) |
|
|
||||||
map("#EXTINF:" + .length + "," + .t + "\n" + $base + "/" + .file)[]'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main playback method
|
# Main playback method
|
||||||
#
|
#
|
||||||
# @argument $1: view
|
# @argument $1: view
|
||||||
@@ -108,28 +63,110 @@ playback() {
|
|||||||
"$PLAYBACK_CMD_PLAY")
|
"$PLAYBACK_CMD_PLAY")
|
||||||
[ "$path" ] || exit 0
|
[ "$path" ] || exit 0
|
||||||
case "$view" in
|
case "$view" in
|
||||||
"$VIEW_ARTIST" | "$VIEW_SEARCH_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ARTISTS" | "$VIEW_LIST_ALBUMS") info "not implemented" ;;
|
"$VIEW_SEARCH_ARTIST" | "$VIEW_LIST_ARTISTS")
|
||||||
"$VIEW_RELEASEGROUP") __generate_playlist "$mbid" "$path" | mpv_play_list >/dev/null ;;
|
list_releasegroups "$mbid" |
|
||||||
"$VIEW_RELEASE") __generate_playlist "$mbid_current" "$path" "$mbid" | mpv_play_list >/dev/null ;;
|
while IFS= read -r rgline; do
|
||||||
|
rgmbid="$(echo "$rgline" | cut -d "$(printf '\t')" -f 4)"
|
||||||
|
rgpath="$(echo "$rgline" | cut -d "$(printf '\t')" -f 5)"
|
||||||
|
[ "$rgpath" ] || continue
|
||||||
|
[ "${queue:-}" ] || queue=""
|
||||||
|
export queue
|
||||||
|
list_releases "$rgmbid" |
|
||||||
|
while IFS= read -r line; do
|
||||||
|
rmbid="$(echo "$line" | cut -d "$(printf '\t')" -f 4)"
|
||||||
|
rpath="$(echo "$line" | cut -d "$(printf '\t')" -f 5)"
|
||||||
|
[ "$rpath" ] || continue
|
||||||
|
if [ ! "$queue" ]; then
|
||||||
|
generate_playlist "$rmbid" "$rpath" | mpv_play_list >/dev/null
|
||||||
|
queue=1
|
||||||
|
else
|
||||||
|
generate_playlist "$rmbid" "$rpath" | mpv_queue_list >/dev/null
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
queue=1
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
"$VIEW_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ALBUMS")
|
||||||
|
list_releases "$mbid" |
|
||||||
|
while IFS= read -r line; do
|
||||||
|
rmbid="$(echo "$line" | cut -d "$(printf '\t')" -f 4)"
|
||||||
|
rpath="$(echo "$line" | cut -d "$(printf '\t')" -f 5)"
|
||||||
|
[ "$rpath" ] || continue
|
||||||
|
if [ ! "${queue:-}" ]; then
|
||||||
|
generate_playlist "$rmbid" "$rpath" | mpv_play_list >/dev/null
|
||||||
|
queue=1
|
||||||
|
else
|
||||||
|
generate_playlist "$rmbid" "$rpath" | mpv_queue_list >/dev/null
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
"$VIEW_RELEASEGROUP") generate_playlist "$mbid" "$path" | mpv_play_list >/dev/null ;;
|
||||||
|
"$VIEW_RELEASE") generate_playlist "$mbid_current" "$path" "$mbid" | mpv_play_list >/dev/null ;;
|
||||||
"$VIEW_PLAYLIST") mpv_play_index $((FZF_POS - 1)) >/dev/null ;;
|
"$VIEW_PLAYLIST") mpv_play_index $((FZF_POS - 1)) >/dev/null ;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
"$PLAYBACK_CMD_QUEUE")
|
"$PLAYBACK_CMD_QUEUE")
|
||||||
[ "$path" ] || exit 0
|
[ "$path" ] || exit 0
|
||||||
case "$view" in
|
case "$view" in
|
||||||
"$VIEW_ARTIST" | "$VIEW_SEARCH_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ARTISTS" | "$VIEW_LIST_ALBUMS") info "not implemented" ;;
|
"$VIEW_SEARCH_ARTIST" | "$VIEW_LIST_ARTISTS")
|
||||||
"$VIEW_RELEASEGROUP") __generate_playlist "$mbid" "$path" | mpv_queue_list >/dev/null ;;
|
list_releasegroups "$mbid" |
|
||||||
"$VIEW_RELEASE") __generate_playlist "$mbid_current" "$path" "$mbid" | mpv_queue_list >/dev/null ;;
|
while IFS= read -r rgline; do
|
||||||
"$VIEW_PLAYLIST") __generate_playlist "$mbid_current" "$path" "$mbid" | mpv_queue_list >/dev/null ;;
|
rgmbid="$(echo "$rgline" | cut -d "$(printf '\t')" -f 4)"
|
||||||
|
rgpath="$(echo "$rgline" | cut -d "$(printf '\t')" -f 5)"
|
||||||
|
[ "$rgpath" ] || continue
|
||||||
|
list_releases "$rgmbid" |
|
||||||
|
while IFS= read -r line; do
|
||||||
|
rmbid="$(echo "$line" | cut -d "$(printf '\t')" -f 4)"
|
||||||
|
rpath="$(echo "$line" | cut -d "$(printf '\t')" -f 5)"
|
||||||
|
[ "$rpath" ] || continue
|
||||||
|
generate_playlist "$rmbid" "$rpath" | mpv_queue_list >/dev/null
|
||||||
|
done
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
"$VIEW_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ALBUMS")
|
||||||
|
list_releases "$mbid" |
|
||||||
|
while IFS= read -r line; do
|
||||||
|
rmbid="$(echo "$line" | cut -d "$(printf '\t')" -f 4)"
|
||||||
|
rpath="$(echo "$line" | cut -d "$(printf '\t')" -f 5)"
|
||||||
|
[ "$rpath" ] || continue
|
||||||
|
generate_playlist "$rmbid" "$rpath" | mpv_queue_list >/dev/null
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
"$VIEW_RELEASEGROUP") generate_playlist "$mbid" "$path" | mpv_queue_list >/dev/null ;;
|
||||||
|
"$VIEW_RELEASE") generate_playlist "$mbid_current" "$path" "$mbid" | mpv_queue_list >/dev/null ;;
|
||||||
|
"$VIEW_PLAYLIST") generate_playlist "$mbid_current" "$path" "$mbid" | mpv_queue_list >/dev/null ;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
"$PLAYBACK_CMD_QUEUE_NEXT")
|
"$PLAYBACK_CMD_QUEUE_NEXT")
|
||||||
[ "$path" ] || exit 0
|
[ "$path" ] || exit 0
|
||||||
case "$view" in
|
case "$view" in
|
||||||
"$VIEW_ARTIST" | "$VIEW_SEARCH_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ARTISTS" | "$VIEW_LIST_ALBUMS") info "not implemented" ;;
|
"$VIEW_SEARCH_ARTIST" | "$VIEW_LIST_ARTISTS")
|
||||||
"$VIEW_RELEASEGROUP") __generate_playlist "$mbid" "$path" | mpv_queue_next_list >/dev/null ;;
|
list_releasegroups "$mbid" |
|
||||||
"$VIEW_RELEASE") __generate_playlist "$mbid_current" "$path" "$mbid" | mpv_queue_next_list >/dev/null ;;
|
while IFS= read -r rgline; do
|
||||||
"$VIEW_PLAYLIST") __generate_playlist "$mbid_current" "$path" "$mbid" | mpv_queue_next_list >/dev/null ;;
|
rgmbid="$(echo "$rgline" | cut -d "$(printf '\t')" -f 4)"
|
||||||
|
rgpath="$(echo "$rgline" | cut -d "$(printf '\t')" -f 5)"
|
||||||
|
[ "$rgpath" ] || continue
|
||||||
|
list_releases "$rgmbid" |
|
||||||
|
while IFS= read -r line; do
|
||||||
|
rmbid="$(echo "$line" | cut -d "$(printf '\t')" -f 4)"
|
||||||
|
rpath="$(echo "$line" | cut -d "$(printf '\t')" -f 5)"
|
||||||
|
[ "$rpath" ] || continue
|
||||||
|
generate_playlist "$rmbid" "$rpath" | mpv_queue_next_list >/dev/null
|
||||||
|
done
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
"$VIEW_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ALBUMS")
|
||||||
|
list_releases "$mbid" |
|
||||||
|
while IFS= read -r line; do
|
||||||
|
rmbid="$(echo "$line" | cut -d "$(printf '\t')" -f 4)"
|
||||||
|
rpath="$(echo "$line" | cut -d "$(printf '\t')" -f 5)"
|
||||||
|
[ "$rpath" ] || continue
|
||||||
|
generate_playlist "$rmbid" "$rpath" | mpv_queue_next_list >/dev/null
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
"$VIEW_RELEASEGROUP") generate_playlist "$mbid" "$path" | mpv_queue_next_list >/dev/null ;;
|
||||||
|
"$VIEW_RELEASE") generate_playlist "$mbid_current" "$path" "$mbid" | mpv_queue_next_list >/dev/null ;;
|
||||||
|
"$VIEW_PLAYLIST") generate_playlist "$mbid_current" "$path" "$mbid" | mpv_queue_next_list >/dev/null ;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
"$PLAYBACK_CMD_TOGGLE_PLAYBACK") mpv_toggle_pause ;;
|
"$PLAYBACK_CMD_TOGGLE_PLAYBACK") mpv_toggle_pause ;;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
# This files provides an interface to manipulate the playlist. The available
|
# This files provides an interface to manipulate the playlist. The available
|
||||||
# commands are defined in the following variables.
|
# commands are defined in the following variables.
|
||||||
if [ ! "${PLAYLIST_LOADED:-}" ]; then
|
if [ ! "${PLAYLIST_LOADED:-}" ]; then
|
||||||
|
# Playlist commands
|
||||||
PLAYLIST_CMD_REMOVE="rm"
|
PLAYLIST_CMD_REMOVE="rm"
|
||||||
PLAYLIST_CMD_UP="up"
|
PLAYLIST_CMD_UP="up"
|
||||||
PLAYLIST_CMD_DOWN="down"
|
PLAYLIST_CMD_DOWN="down"
|
||||||
@@ -11,13 +12,151 @@ if [ ! "${PLAYLIST_LOADED:-}" ]; then
|
|||||||
PLAYLIST_CMD_CLEAR_BELOW="clear-below"
|
PLAYLIST_CMD_CLEAR_BELOW="clear-below"
|
||||||
PLAYLIST_CMD_SHUFFLE="shuffle"
|
PLAYLIST_CMD_SHUFFLE="shuffle"
|
||||||
PLAYLIST_CMD_UNSHUFFLE="unshuffle"
|
PLAYLIST_CMD_UNSHUFFLE="unshuffle"
|
||||||
|
PLAYLIST_CMD_LOAD="load"
|
||||||
export PLAYLIST_CMD_REMOVE PLAYLIST_CMD_UP PLAYLIST_CMD_DOWN \
|
export PLAYLIST_CMD_REMOVE PLAYLIST_CMD_UP PLAYLIST_CMD_DOWN \
|
||||||
PLAYLIST_CMD_CLEAR PLAYLIST_CMD_CLEAR_ABOVE PLAYLIST_CMD_CLEAR_BELOW \
|
PLAYLIST_CMD_CLEAR PLAYLIST_CMD_CLEAR_ABOVE PLAYLIST_CMD_CLEAR_BELOW \
|
||||||
PLAYLIST_CMD_SHUFFLE PLAYLIST_CMD_UNSHUFFLE
|
PLAYLIST_CMD_SHUFFLE PLAYLIST_CMD_UNSHUFFLE PLAYLIST_CMD_LOAD
|
||||||
|
|
||||||
|
# Storage and loading of playlists
|
||||||
|
PLAYLIST_DIRECTORY="${PLAYLIST_DIRECTORY:-"$LOCALDATADIR/playlists"}"
|
||||||
|
[ -d "$PLAYLIST_DIRECTORY" ] || mkdir -p "$PLAYLIST_DIRECTORY"
|
||||||
|
export PLAYLIST_DIRECTORY
|
||||||
|
|
||||||
export PLAYLIST_LOADED=1
|
export PLAYLIST_LOADED=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# List stored playlists
|
||||||
|
#
|
||||||
|
# This prints the names of the stored playlists.
|
||||||
|
stored_playlists() {
|
||||||
|
find "$PLAYLIST_DIRECTORY" -mindepth 1 -maxdepth 1 -type f -printf "$PLYSTORE_PLAYLIST\t%f\n" |
|
||||||
|
sort
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate playlist from MB release ID and path to decoration
|
||||||
|
#
|
||||||
|
# @argument $1: MusicBrainz release ID
|
||||||
|
# @argument $2: Path to decoration file
|
||||||
|
# @argument $3: MusicBrainz track ID to select (optional)
|
||||||
|
generate_playlist() {
|
||||||
|
printf "#EXTM3U\n"
|
||||||
|
dir="$(dirname "$2")"
|
||||||
|
mb_release "$1" |
|
||||||
|
$JQ \
|
||||||
|
--slurpfile decofile "$2" \
|
||||||
|
--arg base "$dir" \
|
||||||
|
--arg deco "$2" \
|
||||||
|
--arg tid "${3:-}" \
|
||||||
|
'$decofile[].tracks as $filenames |
|
||||||
|
. |
|
||||||
|
.id as $rid |
|
||||||
|
.media |
|
||||||
|
length as $l |
|
||||||
|
.[] |
|
||||||
|
.position as $pos |
|
||||||
|
.tracks |
|
||||||
|
if ($tid == "") then . else map(select(.id == $tid)) end |
|
||||||
|
map({
|
||||||
|
t: [
|
||||||
|
$rid,
|
||||||
|
.id,
|
||||||
|
$l,
|
||||||
|
$pos,
|
||||||
|
.number,
|
||||||
|
.length,
|
||||||
|
.title,
|
||||||
|
(."artist-credit" | map([.name, .joinphrase] | join("")) | join("")),
|
||||||
|
$deco
|
||||||
|
] | join("\t"),
|
||||||
|
length: (.length // 0 / 1000 | round | tostring),
|
||||||
|
$pos,
|
||||||
|
number: .number,
|
||||||
|
file: $filenames[.id]
|
||||||
|
}) |
|
||||||
|
map(if(.number | type == "string" and test("^[0-9]+$")) then .number |= tonumber else . end) |
|
||||||
|
sort_by([.pos, .number]) |
|
||||||
|
map("#EXTINF:" + .length + "," + .t + "\n" + $base + "/" + .file)[]'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate m3u playlist from stored playlist
|
||||||
|
#
|
||||||
|
# @argument $1: Playlist file
|
||||||
|
generate_playlist_stored() {
|
||||||
|
f="${1:-}"
|
||||||
|
[ -s "$f" ] || return
|
||||||
|
# Check that we have all releases cached, else fetch missing ones
|
||||||
|
relf=$(mktemp)
|
||||||
|
cut -d "$(printf '\t')" -f 1 "$f" >"$relf"
|
||||||
|
cached "$TYPE_RELEASE" "$relf" || batch_load_missing "$TYPE_RELEASE" <"$relf"
|
||||||
|
jrelf=$(mktemp)
|
||||||
|
# Write json file with all releases
|
||||||
|
cache_get_file_batch "$TYPE_RELEASE" <"$relf" |
|
||||||
|
xargs -d '\n' cat >"$jrelf"
|
||||||
|
# Get associated decorations and write json file with all decorations
|
||||||
|
jpf=$(mktemp)
|
||||||
|
jdecf=$(mktemp)
|
||||||
|
awk -F '\t' \
|
||||||
|
-v rfile="$LOCALDATA_RELEASES" \
|
||||||
|
'BEGIN {
|
||||||
|
OFS="\t"
|
||||||
|
while ((getline < rfile) == 1)
|
||||||
|
release[$1] = $2
|
||||||
|
close(rfile)
|
||||||
|
print "["
|
||||||
|
}
|
||||||
|
NR > 1 { print "," }
|
||||||
|
{ print "{\"rid\":\"" $1 "\",\"tid\":\"" $2 "\",\"deco\":\"" (release[$1] ? release[$1] : "") "\"}" }
|
||||||
|
END {print "]"}' <"$f" >"$jpf"
|
||||||
|
$JQ 'map(.deco) | join("\n")' "$jpf" |
|
||||||
|
grep '.' |
|
||||||
|
xargs -d '\n' cat >"$jdecf"
|
||||||
|
# Merge all data using jq and print playlist
|
||||||
|
printf "#EXTM3U\n"
|
||||||
|
$JQ \
|
||||||
|
--slurpfile deco "$jdecf" \
|
||||||
|
--slurpfile mb "$jrelf" \
|
||||||
|
'$deco as $decorations |
|
||||||
|
$mb as $releases |
|
||||||
|
map(
|
||||||
|
. as $item |
|
||||||
|
first(
|
||||||
|
if ($item.deco | length) > 0 then
|
||||||
|
($item.deco | sub("/[^/]+$"; "")) as $base |
|
||||||
|
first($deco[] | select(.releaseid == $item.rid).tracks | to_entries[] | select(.key == $item.tid).value) as $fn |
|
||||||
|
$base + "/" + $fn
|
||||||
|
else
|
||||||
|
"/dev/null"
|
||||||
|
end
|
||||||
|
) as $p |
|
||||||
|
first(
|
||||||
|
$mb[] | select(.id == $item.rid).media[].tracks[] | select(.id == $item.tid)
|
||||||
|
) as $track |
|
||||||
|
(
|
||||||
|
$track.length // 0 / 1000 | round | tostring
|
||||||
|
) as $length |
|
||||||
|
( if ($item.deco | length) > 0 then $item.deco else "/dev/null" end) as $d |
|
||||||
|
$item + {
|
||||||
|
path: $p,
|
||||||
|
length: $length,
|
||||||
|
t: [
|
||||||
|
$item.rid,
|
||||||
|
$item.tid,
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
$length,
|
||||||
|
$track.title,
|
||||||
|
($track."artist-credit" | map([.name, .joinphrase] | join("")) | join("")),
|
||||||
|
$d
|
||||||
|
] | join("\t")
|
||||||
|
}
|
||||||
|
) |
|
||||||
|
map("#EXTINF:" + .length + "," + .t + "\n" + .path)[]' \
|
||||||
|
"$jpf"
|
||||||
|
# Clean up
|
||||||
|
rm -f "$relf" "$jrelf" "$jpf" "$jdecf"
|
||||||
|
}
|
||||||
|
|
||||||
# Run playback commands
|
# Run playback commands
|
||||||
#
|
#
|
||||||
# @argument $1: playlist command
|
# @argument $1: playlist command
|
||||||
@@ -43,5 +182,10 @@ playlist() {
|
|||||||
;;
|
;;
|
||||||
"$PLAYLIST_CMD_SHUFFLE") mpv_playlist_shuffle ;;
|
"$PLAYLIST_CMD_SHUFFLE") mpv_playlist_shuffle ;;
|
||||||
"$PLAYLIST_CMD_UNSHUFFLE") mpv_playlist_unshuffle ;;
|
"$PLAYLIST_CMD_UNSHUFFLE") mpv_playlist_unshuffle ;;
|
||||||
|
"$PLAYLIST_CMD_LOAD")
|
||||||
|
f="$PLAYLIST_DIRECTORY/${2:-}"
|
||||||
|
[ -s "$f" ] || return
|
||||||
|
generate_playlist_stored "$f" | mpv_play_list >/dev/null
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,49 +2,77 @@
|
|||||||
#
|
#
|
||||||
# For now, only artist previews are supported.
|
# For now, only artist previews are supported.
|
||||||
|
|
||||||
|
if [ ! "${PREVIEW_LOADED:-}" ]; then
|
||||||
|
PREVIEW_NO_WRAP="__DO_NOT_WRAP_THIS_LINE__"
|
||||||
|
PREVIEW_WINDOW_PERCENTAGE="30"
|
||||||
|
export PREVIEW_NO_WRAP PREVIEW_WINDOW_PERCENTAGE
|
||||||
|
|
||||||
|
export PREVIEW_LOADED=1
|
||||||
|
fi
|
||||||
|
|
||||||
# This internal method reshapes the text to be shown in the preview. This
|
# This internal method reshapes the text to be shown in the preview. This
|
||||||
# creates a border on both horizontal ends.
|
# creates a border on both horizontal ends.
|
||||||
#
|
#
|
||||||
# The text is read from stdin.
|
# The text is read from stdin. If a line contains the pattern defined in
|
||||||
|
# PREVIEW_NO_WRAP, then that line will not be folded.
|
||||||
__shape() {
|
__shape() {
|
||||||
cat | tr -d '\r' | fold -s -w "$((FZF_PREVIEW_COLUMNS - 4))" | awk '{print " "$0" "}'
|
#width="$((FZF_PREVIEW_COLUMNS - 4))"
|
||||||
|
width="$((FZF_COLUMNS * PREVIEW_WINDOW_PERCENTAGE / 100 - 4))"
|
||||||
|
while IFS= read -r line; do
|
||||||
|
line="$(printf "%s" "$line" | tr -d '\r')"
|
||||||
|
if printf "%s" "$line" | grep --silent "$PREVIEW_NO_WRAP"; then
|
||||||
|
printf " %s\n" "$line" | sed "s/$PREVIEW_NO_WRAP//g"
|
||||||
|
else
|
||||||
|
printf "%s\n" "$line" |
|
||||||
|
fold -s -w "$width" |
|
||||||
|
awk '{print " "$0" "}'
|
||||||
|
fi
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
# Print preview of artist
|
# Print preview of artist
|
||||||
#
|
#
|
||||||
# @input $1: MusicBrainz artist ID
|
# @input $1: MusicBrainz artist ID
|
||||||
preview_artist() {
|
preview_artist() {
|
||||||
desc=$(mb_artist_enwikipedia "$1" | $JQ '.extract' | __shape)
|
name="$(mb_artist "$1" | $JQ '.name')"
|
||||||
[ "$desc" ] || desc=$(mb_artist_discogs "$1" | $JQ '.profile' | sed 's/\[a=\([^]]*\)\]/\1/g' | __shape)
|
sortname="$(mb_artist "$1" | $JQ '."sort-name"')"
|
||||||
|
disamb="$(mb_artist "$1" | $JQ '.disambiguation')"
|
||||||
|
bio=$(mb_artist_enwikipedia "$1" | $JQ '.extract')
|
||||||
|
[ "$bio" ] || bio=$(mb_artist_discogs "$1" | $JQ '.profile' | sed 's/\[a=\([^]]*\)\]/\1/g')
|
||||||
|
alias="$(mb_artist "$1" | $JQ '.aliases | map(.name) | join("\t")')"
|
||||||
|
startdate="$(mb_artist "$1" | $JQ '."life-span".begin // ""' | head -c 4)"
|
||||||
|
startplace="$(mb_artist "$1" | $JQ '."begin-area".name // ""')"
|
||||||
|
enddate="$(mb_artist "$1" | $JQ '."life-span".end // ""' | head -c 4)"
|
||||||
|
endplace="$(mb_artist "$1" | $JQ '."end-area".name // ""')"
|
||||||
|
url="$(mb_artist "$1" | $JQ '[.relations[] | select(."target-type" == "url") | [.type, .url.resource] | join(";")] | join("\t")')"
|
||||||
if [ "$(mb_artist "$1" | $JQ '.type')" = "Person" ]; then
|
if [ "$(mb_artist "$1" | $JQ '.type')" = "Person" ]; then
|
||||||
# Show birth place and death place of person
|
awk_preview_artist_person \
|
||||||
lsb=$(mb_artist "$1" | $JQ '."life-span".begin // ""' | head -c 4)
|
"$name" \
|
||||||
lse=$(mb_artist "$1" | $JQ '."life-span".end // ""' | head -c 4)
|
"$sortname" \
|
||||||
ab=$(mb_artist "$1" | $JQ '."begin-area".name // ""')
|
"$disamb" \
|
||||||
ae=$(mb_artist "$1" | $JQ '."end-area".name // ""')
|
"$bio" \
|
||||||
if [ "$lsb" ] && [ "$ab" ]; then
|
"$alias" \
|
||||||
begin=$(printf "$APV_DATEPLACE" "$lsb" "$ab")
|
"$startdate" \
|
||||||
elif [ "$lsb" ]; then
|
"$startplace" \
|
||||||
begin=$(printf "$APV_DATE" "$lsb")
|
"$enddate" \
|
||||||
elif [ "$ab" ]; then
|
"$endplace" \
|
||||||
begin=$(printf "$APV_PLACE" "$ab")
|
"$url" |
|
||||||
else
|
__shape
|
||||||
begin=""
|
else
|
||||||
fi
|
awk_preview_artist_group \
|
||||||
if [ "$lse" ] && [ "$ae" ]; then
|
"$name" \
|
||||||
end=$(printf "$APV_DATEPLACE" "$lse" "$ae")
|
"$sortname" \
|
||||||
elif [ "$lse" ]; then
|
"$disamb" \
|
||||||
end=$(printf "$APV_DATE" "$lse")
|
"$bio" \
|
||||||
elif [ "$ae" ]; then
|
"$alias" \
|
||||||
end=$(printf "$APV_PLACE" "$ae")
|
"$startdate" \
|
||||||
else
|
"$startplace" \
|
||||||
end=""
|
"$enddate" \
|
||||||
fi
|
"$endplace" \
|
||||||
[ "$begin" ] && lifespan="$(printf "$APV_BORN" "$begin")"
|
"$url" |
|
||||||
[ "$end" ] && lifespan="$(printf "%s\n$APV_DIED" "$lifespan" "$end")"
|
__shape
|
||||||
fi
|
fi
|
||||||
#link=$(printf "More info:\033]8;;%s\033\\ %s\033]8;;\033\\" "https://musicbrainz.org/" "[MusicBrainz]")
|
#link=$(printf "More info:\033]8;;%s\033\\ %s\033]8;;\033\\" "https://musicbrainz.org/" "[MusicBrainz]")
|
||||||
printf "$APV_FORMAT" "$desc" "${lifespan:-}"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Print message if there is nothing to be shown
|
# Print message if there is nothing to be shown
|
||||||
|
|||||||
44
src/sh/sort.sh
Normal file
44
src/sh/sort.sh
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# Sort methods for generated lists
|
||||||
|
|
||||||
|
if [ ! "${SORT_LOADED:-}" ]; then
|
||||||
|
# Sort specifications
|
||||||
|
#
|
||||||
|
# - No sort
|
||||||
|
# - Alphabetic sort
|
||||||
|
# - Numeric sort
|
||||||
|
SORT_NO="no-sort"
|
||||||
|
SORT_ALPHA="sort-alpha"
|
||||||
|
SORT_NUMERIC="sort-numeric"
|
||||||
|
|
||||||
|
# Artists may be sorted according to the name or the sort-name taken from
|
||||||
|
# MusicBrainz
|
||||||
|
SORT_ARTIST="sort-artist"
|
||||||
|
SORT_ARTIST_SORTNAME="sort-artist-sortname"
|
||||||
|
|
||||||
|
# Release-groups may be sorted according to the release year or the title
|
||||||
|
SORT_RG_TITLE="sort-rg-title"
|
||||||
|
SORT_RG_YEAR="sort-rg-year"
|
||||||
|
export SORT_NO SORT_ALPHA SORT_NUMERIC SORT_ARTIST SORT_ARTIST_SORTNAME \
|
||||||
|
SORT_RG_TITLE SORT_RG_YEAR
|
||||||
|
|
||||||
|
# Configurable default sort
|
||||||
|
SORT_ARTIST_DEFAULT="${SORT_ARTIST_DEFAULT:-"$SORT_ARTIST"}"
|
||||||
|
SORT_RG_DEFAULT="${SORT_RG_DEFAULT:-"$SORT_RG_YEAR"}"
|
||||||
|
export SORT_ARTIST_DEFAULT SORT_RG_DEFAULT
|
||||||
|
|
||||||
|
export SORT_LOADED=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Sorting switches
|
||||||
|
#
|
||||||
|
# @argument $1: Sort specification (may be one of SORT_NO, SORT_ALPHA,
|
||||||
|
# SORT_NUMERIC)
|
||||||
|
#
|
||||||
|
# This method sorts the stream read from stdin.
|
||||||
|
sort_list() {
|
||||||
|
case "${1:-}" in
|
||||||
|
"$SORT_ALPHA") cat | sort -t "$(printf '\t')" -k 2,2 ;;
|
||||||
|
"$SORT_NUMERIC") cat | sort -t "$(printf '\t')" -k 2,2 -n ;;
|
||||||
|
*) cat ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
542
src/sh/theme.sh
542
src/sh/theme.sh
@@ -4,165 +4,405 @@
|
|||||||
#
|
#
|
||||||
# This theme requires fonts that support utf-8, colors, and emojis.
|
# This theme requires fonts that support utf-8, colors, and emojis.
|
||||||
|
|
||||||
# Colors (internal only)
|
if [ ! "${THEME_LOADED:-}" ]; then
|
||||||
ESC=$(printf '\033')
|
# Colors (internal only)
|
||||||
BOLD="${ESC}[1m"
|
ESC=$(printf '\033')
|
||||||
FAINT="${ESC}[2m"
|
BOLD="${ESC}[1m"
|
||||||
UNDERLINE="${ESC}[4m"
|
FAINT="${ESC}[2m"
|
||||||
CARTIST="${ESC}[38;5;209m"
|
ITALIC="${ESC}[3m"
|
||||||
CTITLE="${ESC}[38;5;229m"
|
UNDERLINE="${ESC}[4m"
|
||||||
CRELINFO="${ESC}[38;5;179m"
|
CARTIST="${ESC}[38;5;209m"
|
||||||
CYEAR="${ESC}[38;5;179m"
|
CTITLE="${ESC}[38;5;229m"
|
||||||
CDISAMB="$FAINT${ESC}[38;5;172m"
|
CRELINFO="${ESC}[38;5;179m"
|
||||||
CNOTE="${ESC}[38;5;242m"
|
CYEAR="${ESC}[38;5;179m"
|
||||||
CXXX="${ESC}[38;5;109m"
|
CDISAMB="$FAINT${ESC}[38;5;172m"
|
||||||
CDESC="${ESC}[38;5;254m"
|
CNOTE="${ESC}[38;5;242m"
|
||||||
CLIFE="${ESC}[38;5;251m"
|
CXXX="${ESC}[38;5;109m"
|
||||||
CKB="${ESC}[38;5;224m"
|
CDESC="${ESC}[38;5;254m"
|
||||||
OFF="${ESC}[m"
|
CPURPLE="${ESC}[38;5;213m"
|
||||||
|
CKB="${ESC}[38;5;224m"
|
||||||
|
OFF="${ESC}[m"
|
||||||
|
|
||||||
# Pointers
|
# Pointers
|
||||||
# ========
|
# ========
|
||||||
# Sign that indicates the existence of audio files
|
# Sign that indicates the existence of audio files
|
||||||
FORMAT_LOCAL="${FORMAT_LOCAL:-"🔆"}"
|
FORMAT_LOCAL="${FORMAT_LOCAL:-"🔆"}"
|
||||||
# Pointer to the track currently playing (playlist)
|
export FORMAT_LOCAL
|
||||||
FORMAT_CURRENT="${FORMAT_CURRENT:-"👉"}"
|
|
||||||
export FORMAT_LOCAL FORMAT_CURRENT
|
|
||||||
|
|
||||||
# Input prompt
|
# Input prompt
|
||||||
# =============
|
# =============
|
||||||
# Search prompt
|
# General search prompt (for now only used when choosing one-of-many artist)
|
||||||
SEARCH_PROMPT=${SEARCH_PROMPT:-"🔎 〉"}
|
SEARCH_PROMPT=${SEARCH_PROMPT:-"🔎 〉"}
|
||||||
export SEARCH_PROMPT
|
export SEARCH_PROMPT
|
||||||
|
|
||||||
# Headers
|
# General workings of format strings
|
||||||
# =======
|
#
|
||||||
# Header that displays artist's name
|
# A format string (_FMT) contains placeholders, e.g., <<name>>. These
|
||||||
HEADER_ARTIST="${HEADER_ARTIST:-"🎤 ${CARTIST}%s$OFF 〉"}"
|
# placeholders are filled with the relevant information. A placeholder may
|
||||||
# Header that displays the release-group name after artist's
|
# occur zero times, once, or more than once. There are two types of
|
||||||
HEADER_ARTIST_RELEASEGROUP="${HEADER_ARTIST_RELEASEGROUP:-"🎤 ${CARTIST}%s$OFF 》${CTITLE}%s$OFF 〉"}"
|
# placeholders: strings and items. A placeholder of type string comes with a
|
||||||
# Header that in addition to `HEADER_ARTIST_RELEASEGROUP` also shows some
|
# variable containing a `printf` expression (_FMT_placeholder). This `printf`
|
||||||
# release information
|
# expression may be used to additionally modify the string passed. If the
|
||||||
HEADER_RELEASE="${HEADER_RELEASE:-"🎤 ${CARTIST}%s$OFF 》${CTITLE}%s$OFF 〉%s"}"
|
# string passed is empty, then each corresponding placeholder is replaced
|
||||||
# The release information is formatted as follows (placeholders implicit):
|
# with the empty string, i.e., the `printf` expression is bypassed. A
|
||||||
HEADER_RELEASE_FORMAT="${HEADER_RELEASE_FORMAT:-"${CRELINFO}<<tracks>> tx <<media>> $OFF|$CRELINFO <<label>> <<country>> <<year>>$OFF"}"
|
# placeholder of the alternative type (item) comes with a series of variables
|
||||||
export HEADER_ARTIST HEADER_ARTIST_RELEASEGROUP HEADER_RELEASE HEADER_RELEASE_FORMAT
|
# that encode constants to be used (_FMT_placeholder_XYZ).
|
||||||
|
#
|
||||||
|
# The items in the format string may be separated with "\t". This will induce
|
||||||
|
# a proper representation (using `column`). By default, all fields but the
|
||||||
|
# first are left aligned, and the first field is right aligned. This can be
|
||||||
|
# changed by setting the appropriate FMT_RIGHTALIGN variable. If that
|
||||||
|
# variable is empty, then the first field is right aligned. This means that
|
||||||
|
# at least one field must be right aligned.
|
||||||
|
#
|
||||||
|
# Artist view
|
||||||
|
# ===========
|
||||||
|
# <<flag>> item Indication for locally available audio files
|
||||||
|
# <<type>> item Indicator for single-person artist or group
|
||||||
|
# <<name>> string Artist name
|
||||||
|
# <<disambiguation>> string Disambiguation string
|
||||||
|
#
|
||||||
|
AV_FMT="${AV_FMT:-"<<flag>>\t<<type>> <<name>> <<disambiguation>>"}"
|
||||||
|
AV_FMT_CNT=$(($(printf "$AV_FMT" | tr -cd '\t' | wc -c) + 1))
|
||||||
|
AV_FMT_RIGHTALIGN="${AV_FMT_RIGHTALIGN:-"1"}"
|
||||||
|
AV_FMT_FLAG_LOCAL="${AV_FMT_FLAG_LOCAL:-"$FORMAT_LOCAL"}"
|
||||||
|
AV_FMT_FLAG_NO_LOCAL="${AV_FMT_FLAG_NO_LOCAL:-""}"
|
||||||
|
AV_FMT_TYPE_PERSON="${AV_FMT_TYPE_PERSON:-🧑🎤}"
|
||||||
|
AV_FMT_TYPE_GROUP="${AV_FMT_TYPE_GROUP:-🧑🤝🧑}"
|
||||||
|
AV_FMT_NAME="${AV_FMT_NAME:-"${CARTIST}%s${OFF}"}"
|
||||||
|
AV_FMT_DISAMBIGUATION="${AV_FMT_DISAMBIGUATION:-"${CDISAMB}(%s)${OFF}"}"
|
||||||
|
export AV_FMT AV_FMT_CNT AV_FMT_RIGHTALIGN AV_FMT_FLAG_LOCAL \
|
||||||
|
AV_FMT_FLAG_NO_LOCAL AV_FMT_TYPE_PERSON AV_FMT_TYPE_GROUP AV_FMT_NAME \
|
||||||
|
AV_FMT_DISAMBIGUATION
|
||||||
|
|
||||||
# Artist view
|
# Release-group view
|
||||||
# ===========
|
# ==================
|
||||||
# Artist string for persons
|
# <<flag>> item Indication for locally available audio files
|
||||||
AV_PERSON="${AV_PERSON:-"🧑🎤 $CARTIST<<name>>$OFF"}"
|
# <<type>> item Indicates the type
|
||||||
# Artist string for groups
|
# <<hassecondary>> item Indicates if there is some secondary type or none
|
||||||
AV_GROUP="${AV_GROUP:-"🧑🤝🧑 $CARTIST<<name>>$OFF"}"
|
# <<secondary>> string List of secondary types
|
||||||
# Artist disambiguation string
|
# <<title>> string Title of album
|
||||||
AV_DISAMBIGUATION="${AV_DISAMBIGUATION:-"$CDISAMB(<<disambiguation>>)$OFF"}"
|
# <<artist>> string Artist of album
|
||||||
export AV_PERSON AV_GROUP AV_DISAMBIGUATION
|
# <<year>> string Year of initial release
|
||||||
|
# Note: The above <<secondary>> is of a joint item-string type. See code for
|
||||||
|
# details.
|
||||||
|
RGV_FMT="${RGV_FMT:-"<<flag>>\t<<type>>\t<<hassecondary>>\t<<title>><<artist>> <<year>> <<secondary>>"}"
|
||||||
|
RGV_FMT_CNT=$(($(printf "$RGV_FMT" | tr -cd '\t' | wc -c) + 1))
|
||||||
|
RGV_FMT_RIGHTALIGN="${RGV_FMT_RIGHTALIGN:-"1"}"
|
||||||
|
RGV_FMT_FLAG_LOCAL="${RGV_FMT_FLAG_LOCAL:-"$FORMAT_LOCAL"}"
|
||||||
|
RGV_FMT_FLAG_NO_LOCAL="${RGV_FMT_FLAG_NO_LOCAL:-""}"
|
||||||
|
RGV_FMT_TYPE_SINGLE="${RGV_FMT_TYPE_SINGLE:-"SI 🎶"}"
|
||||||
|
RGV_FMT_TYPE_ALBUM="${RGV_FMT_TYPE_ALBUM:-"LP 💽"}"
|
||||||
|
RGV_FMT_TYPE_EP="${RGV_FMT_TYPE_EP:-"EP 📀"}"
|
||||||
|
RGV_FMT_TYPE_BROADCAST="${RGV_FMT_TYPE_BROADCAST:-"BR 📻"}"
|
||||||
|
RGV_FMT_TYPE_OTHER="${RGV_FMT_TYPE_OTHER:-"OT ❔"}"
|
||||||
|
RGV_FMT_TYPE_UNKNOWN="${RGV_FMT_TYPE_UNKNOWN:-""}"
|
||||||
|
RGV_FMT_HASSECONDARY_YES="${RGV_FMT_HASSECONDARY_YES:-"☼"}"
|
||||||
|
RGV_FMT_HASSECONDARY_NO="${RGV_FMT_HASSECONDARY_NO:-""}"
|
||||||
|
RGV_FMT_SECONDARY="${RGV_FMT_SECONDARY:-"${CNOTE}[☼: %s]${OFF}"}"
|
||||||
|
RGV_FMT_SECONDARY_COMPILATION="${RGV_FMT_SECONDARY_COMPILATION:-"🧩 compilation"}"
|
||||||
|
RGV_FMT_SECONDARY_SOUNDTRACK="${RGV_FMT_SECONDARY_SOUNDTRACK:-"🎬 soundtrack"}"
|
||||||
|
RGV_FMT_SECONDARY_SPOKENWORD="${RGV_FMT_SECONDARY_SPOKENWORD:-"📖 spokenword"}"
|
||||||
|
RGV_FMT_SECONDARY_INTERVIEW="${RGV_FMT_SECONDARY_INTERVIEW:-"💬 interview"}"
|
||||||
|
RGV_FMT_SECONDARY_AUDIOBOOK="${RGV_FMT_SECONDARY_AUDIOBOOK:-"🎧 audiobook"}"
|
||||||
|
RGV_FMT_SECONDARY_AUDIODRAMA="${RGV_FMT_SECONDARY_AUDIODRAMA:-"🎭 audio drama"}"
|
||||||
|
RGV_FMT_SECONDARY_LIVE="${RGV_FMT_SECONDARY_LIVE:-"🎤 live"}"
|
||||||
|
RGV_FMT_SECONDARY_REMIX="${RGV_FMT_SECONDARY_REMIX:-"🔁 remix"}"
|
||||||
|
RGV_FMT_SECONDARY_DJMIX="${RGV_FMT_SECONDARY_DJMIX:-"🪩 DJ-mix"}"
|
||||||
|
RGV_FMT_SECONDARY_MIXTAPE="${RGV_FMT_SECONDARY_MIXTAPE:-"📼 mixtape"}"
|
||||||
|
RGV_FMT_SECONDARY_DEMO="${RGV_FMT_SECONDARY_DEMO:-"🧪 demo"}"
|
||||||
|
RGV_FMT_SECONDARY_FIELDREC="${RGV_FMT_SECONDARY_FIELDREC:-"🌿 field recording"}"
|
||||||
|
RGV_FMT_TITLE="${RGV_FMT_TITLE:-"${CTITLE}%s${OFF}"}"
|
||||||
|
RGV_FMT_ARTIST="${RGV_FMT_ARTIST:-" — ${CARTIST}%s${OFF}"}"
|
||||||
|
RGV_FMT_YEAR="${RGV_FMT_YEAR:-"${CYEAR}(%s)${OFF}"}"
|
||||||
|
export RGV_FMT RGV_FMT_CNT RGV_FMT_RIGHTALIGN RGV_FMT_FLAG_LOCAL \
|
||||||
|
RGV_FMT_FLAG_NO_LOCAL RGV_FMT_TYPE_SINGLE RGV_FMT_TYPE_ALBUM \
|
||||||
|
RGV_FMT_TYPE_EP RGV_FMT_TYPE_BROADCAST RGV_FMT_TYPE_OTHER \
|
||||||
|
RGV_FMT_TYPE_UNKNOWN RGV_FMT_HASSECONDARY_YES RGV_FMT_HASSECONDARY_NO \
|
||||||
|
RGV_FMT_SECONDARY RGV_FMT_SECONDARY_COMPILATION \
|
||||||
|
RGV_FMT_SECONDARY_SOUNDTRACK RGV_FMT_SECONDARY_SPOKENWORD \
|
||||||
|
RGV_FMT_SECONDARY_INTERVIEW RGV_FMT_SECONDARY_AUDIOBOOK \
|
||||||
|
RGV_FMT_SECONDARY_AUDIODRAMA RGV_FMT_SECONDARY_LIVE \
|
||||||
|
RGV_FMT_SECONDARY_REMIX RGV_FMT_SECONDARY_DJMIX \
|
||||||
|
RGV_FMT_SECONDARY_MIXTAPE RGV_FMT_SECONDARY_DEMO RGV_FMT_SECONDARY_FIELDREC \
|
||||||
|
RGV_FMT_TITLE RGV_FMT_ARTIST RGV_FMT_YEAR
|
||||||
|
|
||||||
# Release-group view
|
# Release view
|
||||||
# ==================
|
# ============
|
||||||
# Default release group string
|
# <<flag>> item Indication for locally available audio files
|
||||||
RGV_RELEASE="${RGV_RELEASE:-"${CTITLE}<<title>>$OFF"}"
|
# <<status>> item Release status
|
||||||
# Release group string if the artist name differs from the current artist
|
# <<tracks>> string Total number of track
|
||||||
RGV_RELEASE_W_ARTIST="${RGV_RELEASE_W_ARTIST:-"${CTITLE}<<title>>$OFF — ${CARTIST}<<artist>>$OFF"}"
|
# <<media>> string Media description
|
||||||
# Year of the release group
|
# <<year>> string Release year
|
||||||
RGV_YEAR="${RGV_YEAR:-"${CYEAR}(<<year>>)$OFF"}"
|
# <<country>> string Release country
|
||||||
export RGV_RELEASE RGV_RELEASE_W_ARTIST RGV_YEAR
|
# <<label>> string Release label
|
||||||
|
# <<title>> string Optional titel string
|
||||||
|
# <<artist>> string Optional artist string
|
||||||
|
RV_FMT="${RV_FMT:-"<<flag>>\t<<status>>\t<<tracks>>\t<<media>>\t<<year>>\t<<country>>\t<<label>>\t<<title>> <<artist>>"}"
|
||||||
|
RV_FMT_CNT=$(($(printf "$RV_FMT" | tr -cd '\t' | wc -c) + 1))
|
||||||
|
RV_FMT_RIGHTALIGN="${RV_FMT_RIGHTALIGN:-"1,3"}"
|
||||||
|
RV_FMT_FLAG_LOCAL="${RV_FMT_FLAG_LOCAL:-"$FORMAT_LOCAL"}"
|
||||||
|
RV_FMT_FLAG_NO_LOCAL="${RV_FMT_FLAG_NO_LOCAL:-""}"
|
||||||
|
RV_FMT_STATUS_OFFICIAL="${RV_FMT_STATUS_OFFICIAL:-"🟢"}"
|
||||||
|
RV_FMT_STATUS_PROMO="${RV_FMT_STATUS_PROMO:-"📣"}"
|
||||||
|
RV_FMT_STATUS_BOOTLEG="${RV_FMT_STATUS_BOOTLEG:-"💣"}"
|
||||||
|
RV_FMT_STATUS_PSEUDO="${RV_FMT_STATUS_PSEUDO:-"🌀"}"
|
||||||
|
RV_FMT_STATUS_WITHDRAWN="${RV_FMT_STATUS_WITHDRAWN:-"🔙"}"
|
||||||
|
RV_FMT_STATUS_EXPUNGED="${RV_FMT_STATUS_EXPUNGED:-"🧹"}"
|
||||||
|
RV_FMT_STATUS_CANCELLED="${RV_FMT_STATUS_CANCELLED:-"❌"}"
|
||||||
|
RV_FMT_STATUS_UNKNOWN="${RV_FMT_STATUS_UNKNOWN:-""}"
|
||||||
|
RV_FMT_TRACKS="${RV_FMT_TRACKS:-"${CXXX}%s tracks${OFF}"}"
|
||||||
|
RV_FMT_MEDIA="${RV_FMT_MEDIA:-"${CXXX}%s${OFF}"}"
|
||||||
|
RV_FMT_YEAR="${RV_FMT_YEAR:-"${CYEAR}%s${OFF}"}"
|
||||||
|
RV_FMT_COUNTRY="${RV_FMT_COUNTRY:-"${CYEAR}%s${OFF}"}"
|
||||||
|
RV_FMT_LABEL="${RV_FMT_LABEL:-"${CARTIST}%s${OFF}"}"
|
||||||
|
RV_FMT_TITLE="${RV_FMT_TITLE:-"${FAINT}as${OFF} ${CTITLE}%s${OFF}"}"
|
||||||
|
RV_FMT_ARTIST="${RV_FMT_ARTIST:-"${FAINT}by${OFF} ${CTITLE}%s${OFF}"}"
|
||||||
|
export RV_FMT RV_FMT_CNT RV_FMT_RIGHTALIGN RV_FMT_FLAG_LOCAL \
|
||||||
|
RV_FMT_FLAG_NO_LOCAL RV_FMT_STATUS_OFFICIAL RV_FMT_STATUS_PROMO \
|
||||||
|
RV_FMT_STATUS_BOOTLEG RV_FMT_STATUS_PSEUDO RV_FMT_STATUS_WITHDRAWN \
|
||||||
|
RV_FMT_STATUS_EXPUNGED RV_FMT_STATUS_CANCELLED RV_FMT_STATUS_UNKNOWN \
|
||||||
|
RV_FMT_TRACKS RV_FMT_MEDIA RV_FMT_YEAR RV_FMT_COUNTRY RV_FMT_LABEL \
|
||||||
|
RV_FMT_TITLE RV_FMT_ARTIST
|
||||||
|
|
||||||
# Release-group types
|
# Recording view
|
||||||
# ===================
|
# ==============
|
||||||
# Album
|
# <<flag>> item Indication for locally available audio files
|
||||||
FORMAT_TYPE_ALBUM="${FORMAT_TYPE_ALBUM:-"LP 💽"}"
|
# <<media>> string Media identifier
|
||||||
# EP
|
# <<nr>> string Track number within media
|
||||||
FORMAT_TYPE_EP="${FORMAT_TYPE_EP:-"EP 📀"}"
|
# <<title>> string Track title
|
||||||
# Single
|
# <<artist>> string Track artist
|
||||||
FORMAT_TYPE_SINGLE="${FORMAT_TYPE_SINGLE:-"SI 🎶"}"
|
# <<duration>> string Track duration
|
||||||
# Broadcast
|
REC_FMT="${REC_FMT:-"<<flag>>\t<<media>>\t<<nr>>\t<<title>>\t<<artist>>\t<<duration>>"}"
|
||||||
FORMAT_TYPE_BROADCAST="${FORMAT_TYPE_BROADCAST:-"BR 📻"}"
|
REC_FMT_CNT=$(($(printf "$REC_FMT" | tr -cd '\t' | wc -c) + 1))
|
||||||
# Other
|
REC_FMT_RIGHTALIGN="${REC_FMT_RIGHTALIGN:-"1,2,3"}"
|
||||||
FORMAT_TYPE_OTHER="${FORMAT_TYPE_OTHER:-"OT ❔"}"
|
REC_FMT_FLAG_LOCAL="${REC_FMT_FLAG_LOCAL:-"$FORMAT_LOCAL"}"
|
||||||
# Flag to indicate that the given release group has associated secondary types.
|
REC_FMT_FLAG_NO_LOCAL="${REC_FMT_FLAG_NO_LOCAL:-""}"
|
||||||
FORMAT_TYPE_HAS_SECONDARY="${FORMAT_TYPE_HAS_SECONDARY:-"%s☼"}"
|
REC_FMT_MEDIA="${REC_FMT_MEDIA:-"${CNOTE}${FAINT}%s${OFF}"}"
|
||||||
# Style to represent secondary types (takes one %s placeholder)
|
REC_FMT_NR="${REC_FMT_NR:-"${CNOTE}%s${OFF}"}"
|
||||||
FORMAT_TYPE_SECONDARY="${FORMAT_TYPE_SECONDARY:-"${CNOTE}[☼: %s]$OFF"}"
|
REC_FMT_TITLE="${REC_FMT_TITLE:-"${CTITLE}%s${OFF}"}"
|
||||||
# Secondary types
|
REC_FMT_ARTIST="${REC_FMT_ARTIST:-"${CARTIST}%s${OFF}"}"
|
||||||
FORMAT_TYPE_SECONDARY_COMPILATION="${FORMAT_TYPE_SECONDARY_COMPILATION:-"🧩 compilation"}"
|
REC_FMT_DURATION="${REC_FMT_DURATION:-"${CXXX}%s${OFF}"}"
|
||||||
FORMAT_TYPE_SECONDARY_SOUNDTRACK="${FORMAT_TYPE_SECONDARY_SOUNDTRACK:-"🎬 soundtrack"}"
|
export REC_FMT REC_FMT_CNT REC_FMT_RIGHTALIGN REC_FMT_FLAG_LOCAL \
|
||||||
FORMAT_TYPE_SECONDARY_SPOKENWORD="${FORMAT_TYPE_SECONDARY_SPOKENWORD:-"📖 spokenword"}"
|
REC_FMT_FLAG_NO_LOCAL REC_FMT_MEDIA REC_FMT_NR REC_FMT_TITLE \
|
||||||
FORMAT_TYPE_SECONDARY_INTERVIEW="${FORMAT_TYPE_SECONDARY_INTERVIEW:-"💬 interview"}"
|
REC_FMT_ARTIST REC_FMT_DURATION
|
||||||
FORMAT_TYPE_SECONDARY_AUDIOBOOK="${FORMAT_TYPE_SECONDARY_AUDIOBOOK:-"🎧 audiobook"}"
|
|
||||||
FORMAT_TYPE_SECONDARY_AUDIODRAMA="${FORMAT_TYPE_SECONDARY_AUDIODRAMA:-"🎭 audio drama"}"
|
|
||||||
FORMAT_TYPE_SECONDARY_LIVE="${FORMAT_TYPE_SECONDARY_LIVE:-"🎤 live"}"
|
|
||||||
FORMAT_TYPE_SECONDARY_REMIX="${FORMAT_TYPE_SECONDARY_REMIX:-"🔁 remix"}"
|
|
||||||
FORMAT_TYPE_SECONDARY_DJMIX="${FORMAT_TYPE_SECONDARY_DJMIX:-"🪩 DJ-mix"}"
|
|
||||||
FORMAT_TYPE_SECONDARY_MIXTAPE="${FORMAT_TYPE_SECONDARY_MIXTAPE:-"📼 mixtape"}"
|
|
||||||
FORMAT_TYPE_SECONDARY_DEMO="${FORMAT_TYPE_SECONDARY_DEMO:-"🧪 demo"}"
|
|
||||||
FORMAT_TYPE_SECONDARY_FIELDREC="${FORMAT_TYPE_SECONDARY_FIELDREC:-"🌿 field recording"}"
|
|
||||||
export FORMAT_TYPE_ALBUM FORMAT_TYPE_EP FORMAT_TYPE_SINGLE \
|
|
||||||
FORMAT_TYPE_BROADCAST FORMAT_TYPE_OTHER FORMAT_TYPE_HAS_SECONDARY \
|
|
||||||
FORMAT_TYPE_SECONDARY FORMAT_TYPE_SECONDARY_COMPILATION \
|
|
||||||
FORMAT_TYPE_SECONDARY_SOUNDTRACK FORMAT_TYPE_SECONDARY_SPOKENWORD \
|
|
||||||
FORMAT_TYPE_SECONDARY_INTERVIEW FORMAT_TYPE_SECONDARY_AUDIOBOOK \
|
|
||||||
FORMAT_TYPE_SECONDARY_AUDIODRAMA FORMAT_TYPE_SECONDARY_LIVE \
|
|
||||||
FORMAT_TYPE_SECONDARY_REMIX FORMAT_TYPE_SECONDARY_DJMIX \
|
|
||||||
FORMAT_TYPE_SECONDARY_MIXTAPE FORMAT_TYPE_SECONDARY_DEMO \
|
|
||||||
FORMAT_TYPE_SECONDARY_FIELDREC
|
|
||||||
|
|
||||||
# Artist Preview
|
# Recording view (playlist)
|
||||||
# ==============
|
# =========================
|
||||||
# Main preview format. Takes two %s placeholder. The first is for the artist
|
# <<playing>> item Mark for currently playing track
|
||||||
# biography. The second for the life span.
|
# <<title>> string Track title
|
||||||
APV_FORMAT="${APV_FORMAT:-"\n\n${CDESC}%s${OFF}\n\n${CLIFE}%s${OFF}"}"
|
# <<artist>> string Track artist
|
||||||
# Specification of a date
|
# <<duration>> string Track duration
|
||||||
APV_DATE="${APV_DATE:-"%s"}"
|
PLYLST_FMT="${PLYLST_FMT:-"<<playing>>\t<<title>>\t<<artist>>\t<<duration>>"}"
|
||||||
# Specification of a place
|
PLYLST_FMT_CNT=$(($(printf "$PLYLST_FMT" | tr -cd '\t' | wc -c) + 1))
|
||||||
APV_PLACE="${APV_PLACE:-"%s"}"
|
PLYLST_FMT_RIGHTALIGN="${PLYLST_FMT_RIGHTALIGN:-"1"}"
|
||||||
# Specification of a date and a place (in that order)
|
PLYLST_FMT_PLAYING_YES="${PLYLST_FMT_PLAYING_YES:-"👉"}"
|
||||||
APV_DATEPLACE="${APV_DATEPLACE:-"$APV_DATE, $APV_PLACE"}"
|
PLYLST_FMT_PLAYING_NO="${PLYLST_FMT_PLAYING_NO:-""}"
|
||||||
# String to represent when/where a person is born
|
PLYLST_FMT_TITLE="${PLYLST_FMT_TITLE:-"${CTITLE}%s${OFF}"}"
|
||||||
APV_BORN="${APV_BORN:-"🍼 Born: %s"}"
|
PLYLST_FMT_ARTIST="${PLYLST_FMT_ARTIST:-"${CARTIST}%s${OFF}"}"
|
||||||
# String to represent when/where a person died
|
PLYLST_FMT_DURATION="${PLYLST_FMT_DURATION:-"${CXXX}%s${OFF}"}"
|
||||||
APV_DIED="${APV_DIED:-"🕯️ Died: %s"}"
|
export PLYLST_FMT PLYLST_FMT_CNT PLYLST_FMT_RIGHTALIGN \
|
||||||
export APV_FORMAT APV_DATE APV_PLACE APV_DATEPLACE APV_BORN APV_DIED
|
PLYLST_FMT_PLAYING_YES PLYLST_FMT_PLAYING_NO PLYLST_FMT_TITLE \
|
||||||
|
PLYLST_FMT_ARTIST PLYLST_FMT_DURATION
|
||||||
|
|
||||||
# Release view
|
# Headers
|
||||||
# ============
|
# =======
|
||||||
# Format of a string that represents a release.
|
# These header strings are based on the respective view and its fields
|
||||||
RV_FORMAT="${RV_FORMAT:-"<<status>>\t${CXXX}<<tracks>> tracks\t<<media>>$OFF\t${CYEAR}<<year>>\t<<country>>$OFF\t${CARTIST}<<label>>$OFF"}"
|
# defined above.
|
||||||
# Additional string to display the release title and artist name
|
#
|
||||||
RV_TITLE_ARTIST="${RV_TITLE_ARTIST:-"${FAINT}as ${CTITLE}<<title>>$OFF by ${FAINT}${CARTIST}<<artist>>$OFF"}"
|
# Header that displays artist's name (based on artist view)
|
||||||
# Additional string to display the release title
|
HEADER_ARTIST_FMT="${HEADER_ARTIST_FMT:-"🎤\t<<name>> 〉"}"
|
||||||
RV_TITLE="${RV_TITLE:-"${FAINT}as ${CTITLE}<<title>>$OFF"}"
|
HEADER_ARTIST_FMT_CNT=$(($(printf "$HEADER_ARTIST_FMT" | tr -cd '\t' | wc -c) + 1))
|
||||||
# Additional string to display the artist
|
HEADER_ARTIST_FMT_RIGHTALIGN="${HEADER_ARTIST_FMT_RIGHTALIGN:-"1"}"
|
||||||
RV_ARTIST="${RV_ARTIST:-"${FAINT}by ${CARTIST}<<artist>>$OFF"}"
|
HEADER_ARTIST_FMT_FLAG_LOCAL="${HEADER_ARTIST_FMT_FLAG_LOCAL:-"$AV_FMT_FLAG_LOCAL"}"
|
||||||
export RV_FORMAT RV_TITLE_ARTIST RV_TITLE RV_ARTIST
|
HEADER_ARTIST_FMT_FLAG_NO_LOCAL="${HEADER_ARTIST_FMT_FLAG_NO_LOCAL:-"$AV_FMT_FLAG_NO_LOCAL"}"
|
||||||
|
HEADER_ARTIST_FMT_TYPE_PERSON="${HEADER_ARTIST_FMT_TYPE_PERSON:-"$AV_FMT_TYPE_PERSON"}"
|
||||||
|
HEADER_ARTIST_FMT_TYPE_GROUP="${HEADER_ARTIST_FMT_TYPE_GROUP:-"$AV_FMT_TYPE_GROUP"}"
|
||||||
|
HEADER_ARTIST_FMT_NAME="${HEADER_ARTIST_FMT_NAME:-"$AV_FMT_NAME"}"
|
||||||
|
HEADER_ARTIST_FMT_DISAMBIGUATION="${HEADER_ARTIST_FMT_DISAMBIGUATION:-"$AV_FMT_DISAMBIGUATION"}"
|
||||||
|
export HEADER_ARTIST_FMT HEADER_ARTIST_FMT_CNT HEADER_ARTIST_FMT_RIGHTALIGN \
|
||||||
|
HEADER_ARTIST_FMT_FLAG_LOCAL HEADER_ARTIST_FMT_FLAG_NO_LOCAL \
|
||||||
|
HEADER_ARTIST_FMT_TYPE_PERSON HEADER_ARTIST_FMT_TYPE_GROUP \
|
||||||
|
HEADER_ARTIST_FMT_NAME HEADER_ARTIST_FMT_DISAMBIGUATION
|
||||||
|
|
||||||
# Release Status
|
# Header that displays the release-group (based on release-group view)
|
||||||
# ==============
|
HEADER_RG_FMT="${HEADER_RG_FMT:-"🎤\t<<artist>> 》<<title>> 〉"}"
|
||||||
FORMAT_STATUS_OFFICIAL="${FORMAT_STATUS_OFFICIAL:-"🟢"}"
|
HEADER_RG_FMT_CNT=$(($(printf "$HEADER_RG_FMT" | tr -cd '\t' | wc -c) + 1))
|
||||||
FORMAT_STATUS_PROMO="${FORMAT_STATUS_PROMO:-"📣"}"
|
HEADER_RG_FMT_RIGHTALIGN="${HEADER_RG_FMT_RIGHTALIGN:-"1"}"
|
||||||
FORMAT_STATUS_BOOTLEG="${FORMAT_STATUS_BOOTLEG:-"💣"}"
|
HEADER_RG_FMT_FLAG_LOCAL="${HEADER_RG_FMT_FLAG_LOCAL:-"$RGV_FMT_FLAG_LOCAL"}"
|
||||||
FORMAT_STATUS_PSEUDO="${FORMAT_STATUS_PSEUDO:-"🌀"}"
|
HEADER_RG_FMT_FLAG_NO_LOCAL="${HEADER_RG_FMT_FLAG_NO_LOCAL:-"$RGV_FMT_FLAG_NO_LOCAL"}"
|
||||||
FORMAT_STATUS_WITHDRAWN="${FORMAT_STATUS_WITHDRAWN:-"🔙"}"
|
HEADER_RG_FMT_TYPE_SINGLE="${HEADER_RG_FMT_TYPE_SINGLE:-"$RGV_FMT_TYPE_SINGLE"}"
|
||||||
FORMAT_STATUS_EXPUNGED="${FORMAT_STATUS_EXPUNGED:-"🧹"}"
|
HEADER_RG_FMT_TYPE_ALBUM="${HEADER_RG_FMT_TYPE_ALBUM:-"$RGV_FMT_TYPE_ALBUM"}"
|
||||||
FORMAT_STATUS_CANCELLED="${FORMAT_STATUS_CANCELLED:-"❌"}"
|
HEADER_RG_FMT_TYPE_EP="${HEADER_RG_FMT_TYPE_EP:-"$RGV_FMT_TYPE_EP"}"
|
||||||
export FORMAT_STATUS_OFFICIAL FORMAT_STATUS_PROMO FORMAT_STATUS_BOOTLEG \
|
HEADER_RG_FMT_TYPE_BROADCAST="${HEADER_RG_FMT_TYPE_BROADCAST:-"$RGV_FMT_TYPE_BROADCAST"}"
|
||||||
FORMAT_STATUS_PSEUDO FORMAT_STATUS_WITHDRAWN FORMAT_STATUS_EXPUNGED \
|
HEADER_RG_FMT_TYPE_OTHER="${HEADER_RG_FMT_TYPE_OTHER:-"$RGV_FMT_TYPE_OTHER"}"
|
||||||
FORMAT_STATUS_CANCELLED
|
HEADER_RG_FMT_TYPE_UNKNOWN="${HEADER_RG_FMT_TYPE_UNKNOWN:-"$RGV_FMT_TYPE_UNKNOWN"}"
|
||||||
|
HEADER_RG_FMT_HASSECONDARY_YES="${HEADER_RG_FMT_HASSECONDARY_YES:-"$RGV_FMT_HASSECONDARY_YES"}"
|
||||||
|
HEADER_RG_FMT_HASSECONDARY_NO="${HEADER_RG_FMT_HASSECONDARY_NO:-"$RGV_FMT_HASSECONDARY_NO"}"
|
||||||
|
HEADER_RG_FMT_SECONDARY="${HEADER_RG_FMT_SECONDARY:-"$RGV_FMT_SECONDARY"}"
|
||||||
|
HEADER_RG_FMT_SECONDARY_COMPILATION="${HEADER_RG_FMT_SECONDARY_COMPILATION:-"$RGV_FMT_SECONDARY_COMPILATION"}"
|
||||||
|
HEADER_RG_FMT_SECONDARY_SOUNDTRACK="${HEADER_RG_FMT_SECONDARY_SOUNDTRACK:-"$RGV_FMT_SECONDARY_SOUNDTRACK"}"
|
||||||
|
HEADER_RG_FMT_SECONDARY_SPOKENWORD="${HEADER_RG_FMT_SECONDARY_SPOKENWORD:-"$RGV_FMT_SECONDARY_SPOKENWORD"}"
|
||||||
|
HEADER_RG_FMT_SECONDARY_INTERVIEW="${HEADER_RG_FMT_SECONDARY_INTERVIEW:-"$RGV_FMT_SECONDARY_INTERVIEW"}"
|
||||||
|
HEADER_RG_FMT_SECONDARY_AUDIOBOOK="${HEADER_RG_FMT_SECONDARY_AUDIOBOOK:-"$RGV_FMT_SECONDARY_AUDIOBOOK"}"
|
||||||
|
HEADER_RG_FMT_SECONDARY_AUDIODRAMA="${HEADER_RG_FMT_SECONDARY_AUDIODRAMA:-"$RGV_FMT_SECONDARY_AUDIODRAMA"}"
|
||||||
|
HEADER_RG_FMT_SECONDARY_LIVE="${HEADER_RG_FMT_SECONDARY_LIVE:-"$RGV_FMT_SECONDARY_LIVE"}"
|
||||||
|
HEADER_RG_FMT_SECONDARY_REMIX="${HEADER_RG_FMT_SECONDARY_REMIX:-"$RGV_FMT_SECONDARY_REMIX"}"
|
||||||
|
HEADER_RG_FMT_SECONDARY_DJMIX="${HEADER_RG_FMT_SECONDARY_DJMIX:-"$RGV_FMT_SECONDARY_DJMIX"}"
|
||||||
|
HEADER_RG_FMT_SECONDARY_MIXTAPE="${HEADER_RG_FMT_SECONDARY_MIXTAPE:-"$RGV_FMT_SECONDARY_MIXTAPE"}"
|
||||||
|
HEADER_RG_FMT_SECONDARY_DEMO="${HEADER_RG_FMT_SECONDARY_DEMO:-"$RGV_FMT_SECONDARY_DEMO"}"
|
||||||
|
HEADER_RG_FMT_SECONDARY_FIELDREC="${HEADER_RG_FMT_SECONDARY_FIELDREC:-"$RGV_FMT_SECONDARY_FIELDREC"}"
|
||||||
|
HEADER_RG_FMT_TITLE="${HEADER_RG_FMT_TITLE:-"$RGV_FMT_TITLE"}"
|
||||||
|
HEADER_RG_FMT_ARTIST="${HEADER_RG_FMT_ARTIST:-"${CARTIST}%s${OFF}"}"
|
||||||
|
HEADER_RG_FMT_YEAR="${HEADER_RG_FMT_YEAR:-"$RGV_FMT_YEAR"}"
|
||||||
|
export HEADER_RG_FMT HEADER_RG_FMT_CNT HEADER_RG_FMT_RIGHTALIGN \
|
||||||
|
HEADER_RG_FMT_FLAG_LOCAL HEADER_RG_FMT_FLAG_NO_LOCAL \
|
||||||
|
HEADER_RG_FMT_TYPE_SINGLE HEADER_RG_FMT_TYPE_ALBUM HEADER_RG_FMT_TYPE_EP \
|
||||||
|
HEADER_RG_FMT_TYPE_BROADCAST HEADER_RG_FMT_TYPE_OTHER \
|
||||||
|
HEADER_RG_FMT_TYPE_UNKNOWN HEADER_RG_FMT_HASSECONDARY_YES \
|
||||||
|
HEADER_RG_FMT_HASSECONDARY_NO HEADER_RG_FMT_SECONDARY \
|
||||||
|
HEADER_RG_FMT_SECONDARY_COMPILATION HEADER_RG_FMT_SECONDARY_SOUNDTRACK \
|
||||||
|
HEADER_RG_FMT_SECONDARY_SPOKENWORD HEADER_RG_FMT_SECONDARY_INTERVIEW \
|
||||||
|
HEADER_RG_FMT_SECONDARY_AUDIOBOOK HEADER_RG_FMT_SECONDARY_AUDIODRAMA \
|
||||||
|
HEADER_RG_FMT_SECONDARY_LIVE HEADER_RG_FMT_SECONDARY_REMIX \
|
||||||
|
HEADER_RG_FMT_SECONDARY_DJMIX HEADER_RG_FMT_SECONDARY_MIXTAPE \
|
||||||
|
HEADER_RG_FMT_SECONDARY_DEMO HEADER_RG_FMT_SECONDARY_FIELDREC \
|
||||||
|
HEADER_RG_FMT_TITLE HEADER_RG_FMT_ARTIST HEADER_RG_FMT_YEAR
|
||||||
|
|
||||||
# Recording view
|
# Header that displays the release (based on release view)
|
||||||
# ==============
|
HEADER_R_FMT="${HEADER_R_FMT:-"🎤\t<<artist>> 》<<title>> 〉<<tracks>> ${CRELINFO}tx${OFF} <<media>> | <<label>> <<country>> <<year>>"}"
|
||||||
# Format of a track in a release
|
HEADER_R_FMT_CNT=$(($(printf "$HEADER_R_FMT" | tr -cd '\t' | wc -c) + 1))
|
||||||
REC_FORMAT="${REC_FORMAT:-"${CNOTE}${FAINT}<<med>>\t${CNOTE}<<nr>>$OFF\t${CTITLE}<<title>>\t${CARTIST}<<artist>>\t${CXXX}<<duration>>$OFF"}"
|
HEADER_R_FMT_RIGHTALIGN="${HEADER_R_FMT_RIGHTALIGN:-"1"}"
|
||||||
# Format of a track in the playlist
|
HEADER_R_FMT_FLAG_LOCAL="${HEADER_R_FMT_FLAG_LOCAL:-"$RV_FMT_FLAG_LOCAL"}"
|
||||||
REC_FORMAT_NO_NUMBER="${REC_FORMAT_NO_NUMBER:-"${CTITLE}<<title>>\t${CARTIST}<<artist>>\t${CXXX}<<duration>>$OFF"}"
|
HEADER_R_FMT_FLAG_NO_LOCAL="${HEADER_R_FMT_FLAG_NO_LOCAL:-"$RV_FMT_FLAG_NO_LOCAL"}"
|
||||||
export REC_FORMAT REC_FORMAT_NO_NUMBER
|
HEADER_R_FMT_STATUS_OFFICIAL="${HEADER_R_FMT_STATUS_OFFICIAL:-"$RV_FMT_STATUS_OFFICIAL"}"
|
||||||
|
HEADER_R_FMT_STATUS_PROMO="${HEADER_R_FMT_STATUS_PROMO:-"$RV_FMT_STATUS_PROMO"}"
|
||||||
|
HEADER_R_FMT_STATUS_BOOTLEG="${HEADER_R_FMT_STATUS_BOOTLEG:-"$RV_FMT_STATUS_BOOTLEG"}"
|
||||||
|
HEADER_R_FMT_STATUS_PSEUDO="${HEADER_R_FMT_STATUS_PSEUDO:-"$RV_FMT_STATUS_PSEUDO"}"
|
||||||
|
HEADER_R_FMT_STATUS_WITHDRAWN="${HEADER_R_FMT_STATUS_WITHDRAWN:-"$RV_FMT_STATUS_WITHDRAWN"}"
|
||||||
|
HEADER_R_FMT_STATUS_EXPUNGED="${HEADER_R_FMT_STATUS_EXPUNGED:-"$RV_FMT_STATUS_EXPUNGED"}"
|
||||||
|
HEADER_R_FMT_STATUS_CANCELLED="${HEADER_R_FMT_STATUS_CANCELLED:-"$RV_FMT_STATUS_CANCELLED"}"
|
||||||
|
HEADER_R_FMT_STATUS_UNKNOWN="${HEADER_R_FMT_STATUS_UNKNOWN:-"$RV_FMT_STATUS_UNKNOWN"}"
|
||||||
|
HEADER_R_FMT_TRACKS="${HEADER_R_FMT_TRACKS:-"${CRELINFO}%s${OFF}"}"
|
||||||
|
HEADER_R_FMT_MEDIA="${HEADER_R_FMT_MEDIA:-"${CRELINFO}%s${OFF}"}"
|
||||||
|
HEADER_R_FMT_YEAR="${HEADER_R_FMT_YEAR:-"${CRELINFO}%s${OFF}"}"
|
||||||
|
HEADER_R_FMT_COUNTRY="${HEADER_R_FMT_COUNTRY:-"${CRELINFO}%s${OFF}"}"
|
||||||
|
HEADER_R_FMT_LABEL="${HEADER_R_FMT_LABEL:-"${CRELINFO}%s${OFF}"}"
|
||||||
|
HEADER_R_FMT_TITLE="${HEADER_R_FMT_TITLE:-"${CTITLE}%s${OFF}"}"
|
||||||
|
HEADER_R_FMT_ARTIST="${HEADER_R_FMT_ARTIST:-"${CARTIST}%s${OFF}"}"
|
||||||
|
export HEADER_R_FMT HEADER_R_FMT_CNT HEADER_R_FMT_RIGHTALIGN \
|
||||||
|
HEADER_R_FMT_FLAG_LOCAL HEADER_R_FMT_FLAG_NO_LOCAL \
|
||||||
|
HEADER_R_FMT_STATUS_OFFICIAL HEADER_R_FMT_STATUS_PROMO \
|
||||||
|
HEADER_R_FMT_STATUS_BOOTLEG HEADER_R_FMT_STATUS_PSEUDO \
|
||||||
|
HEADER_R_FMT_STATUS_WITHDRAWN HEADER_R_FMT_STATUS_EXPUNGED \
|
||||||
|
HEADER_R_FMT_STATUS_CANCELLED HEADER_R_FMT_STATUS_UNKNOWN \
|
||||||
|
HEADER_R_FMT_TRACKS HEADER_R_FMT_MEDIA HEADER_R_FMT_YEAR \
|
||||||
|
HEADER_R_FMT_COUNTRY HEADER_R_FMT_LABEL HEADER_R_FMT_TITLE \
|
||||||
|
HEADER_R_FMT_ARTIST
|
||||||
|
|
||||||
# Keybinding themes
|
# Artist Preview
|
||||||
# =================
|
# ==============
|
||||||
# Format keybinding group
|
# Lines that contain the pattern defined in PREVIEW_NO_WRAP (see
|
||||||
KBF_GROUP="${KBF_GROUP:-"${UNDERLINE}${CKB}%s$OFF"}"
|
# `src/sh/preview.sh`) will not be wrapped.
|
||||||
# Format key
|
#
|
||||||
KBF_KEY="${KBF_KEY:-"${BOLD}${CKB}%s$OFF"}"
|
# We distinguish between single-person and group artists.
|
||||||
# Format description
|
#
|
||||||
KBF_DESC="${KBF_DESC:-"${CKB}%s$OFF"}"
|
# <<name>> | string | Artist name
|
||||||
export KBF_GROUP KBF_KEY KBF_DESC
|
# <<sortname>> | string | Artist sort name
|
||||||
|
# <<bio>> | string | Artist biography
|
||||||
|
# <<disambiguation>> | string | Artist disambiguation string
|
||||||
|
# <<alias>> | higher-order placeholder | Placeholder for aliases
|
||||||
|
# <<start> | higher-order placeholder | Placeholder for start string
|
||||||
|
# <<end>> | higher-order placeholder | Placeholder for end string
|
||||||
|
# <<url>> | higher-order placeholder | Placeholder for links
|
||||||
|
PREVIEW_ARTIST_PERSON_FMT="${PREVIEW_ARTIST_PERSON_FMT:-"\n\n<<bio>><<alias>><<start>><<end>>\n<<url>>"}"
|
||||||
|
PREVIEW_ARTIST_PERSON_NAME="${PREVIEW_ARTIST_PERSON_NAME:-"%s"}"
|
||||||
|
PREVIEW_ARTIST_PERSON_SORTNAME="${PREVIEW_ARTIST_PERSON_SORTNAME:-"%s"}"
|
||||||
|
PREVIEW_ARTIST_PERSON_BIO="${PREVIEW_ARTIST_PERSON_BIO:-"${CDESC}%s${OFF}\n\n"}"
|
||||||
|
PREVIEW_ARTIST_PERSON_DISAMB="${PREVIEW_ARTIST_PERSON_DISAMB:-"%s"}"
|
||||||
|
PREVIEW_ARTIST_PERSON_ALIAS="${PREVIEW_ARTIST_PERSON_ALIAS:-"${FAINT}Also known as ${ITALIC}%s${OFF}\n\n"}"
|
||||||
|
PREVIEW_ARTIST_PERSON_ALIAS_JOIN="${PREVIEW_ARTIST_PERSON_ALIAS_JOIN:-"%s, %s"}"
|
||||||
|
PREVIEW_ARTIST_PERSON_START="${PREVIEW_ARTIST_PERSON_START:-"🍼 Born: %s\n"}"
|
||||||
|
PREVIEW_ARTIST_PERSON_START_FMT="${PREVIEW_ARTIST_PERSON_START_FMT:-"<<startdate>> <<startplace>>"}"
|
||||||
|
PREVIEW_ARTIST_PERSON_START_STARTDATE="${PREVIEW_ARTIST_PERSON_START_STARTDATE:-"%s"}"
|
||||||
|
PREVIEW_ARTIST_PERSON_START_STARTPLACE="${PREVIEW_ARTIST_PERSON_START_STARTPLACE:-"in %s"}"
|
||||||
|
PREVIEW_ARTIST_PERSON_END="${PREVIEW_ARTIST_PERSON_END:-"🕯️ Died: %s\n"}"
|
||||||
|
PREVIEW_ARTIST_PERSON_END_FMT="${PREVIEW_ARTIST_PERSON_END_FMT:-"<<enddate>> <<endplace>>"}"
|
||||||
|
PREVIEW_ARTIST_PERSON_END_ENDDATE="${PREVIEW_ARTIST_PERSON_END_ENDDATE:-"%s"}"
|
||||||
|
PREVIEW_ARTIST_PERSON_END_ENDPLACE="${PREVIEW_ARTIST_PERSON_END_ENDPLACE:-"in %s"}"
|
||||||
|
PREVIEW_ARTIST_PERSON_URL="${PREVIEW_ARTIST_PERSON_URL:-"\n%s\n"}"
|
||||||
|
PREVIEW_ARTIST_PERSON_URL_JOIN="${PREVIEW_ARTIST_PERSON_URL_JOIN:-"%s\n%s"}"
|
||||||
|
PREVIEW_ARTIST_PERSON_URL_FMT="${PREVIEW_ARTIST_PERSON_URL_FMT:-"${PREVIEW_NO_WRAP}<<urlindex>>: <<urlname>> <<urllink>>\n"}"
|
||||||
|
PREVIEW_ARTIST_PERSON_URL_URLINDEX="${PREVIEW_ARTIST_PERSON_URL_URLINDEX:-"${CDISAMB}%3d${OFF}"}"
|
||||||
|
PREVIEW_ARTIST_PERSON_URL_URLNAME="${PREVIEW_ARTIST_PERSON_URL_URLNAME:-"${CDESC}%s${OFF}"}"
|
||||||
|
PREVIEW_ARTIST_PERSON_URL_URLLINK="${PREVIEW_ARTIST_PERSON_URL_URLLINK:-"${FAINT}%s${OFF}"}"
|
||||||
|
export PREVIEW_ARTIST_PERSON_FMT PREVIEW_ARTIST_PERSON_NAME \
|
||||||
|
PREVIEW_ARTIST_PERSON_SORTNAME PREVIEW_ARTIST_PERSON_BIO \
|
||||||
|
PREVIEW_ARTIST_PERSON_DISAMB PREVIEW_ARTIST_PERSON_ALIAS \
|
||||||
|
PREVIEW_ARTIST_PERSON_ALIAS_JOIN PREVIEW_ARTIST_PERSON_START \
|
||||||
|
PREVIEW_ARTIST_PERSON_START_FMT PREVIEW_ARTIST_PERSON_START_STARTDATE \
|
||||||
|
PREVIEW_ARTIST_PERSON_START_STARTPLACE PREVIEW_ARTIST_PERSON_END \
|
||||||
|
PREVIEW_ARTIST_PERSON_END_FMT PREVIEW_ARTIST_PERSON_END_ENDDATE \
|
||||||
|
PREVIEW_ARTIST_PERSON_END_ENDPLACE PREVIEW_ARTIST_PERSON_URL \
|
||||||
|
PREVIEW_ARTIST_PERSON_URL_JOIN PREVIEW_ARTIST_PERSON_URL_FMT \
|
||||||
|
PREVIEW_ARTIST_PERSON_URL_URLINDEX PREVIEW_ARTIST_PERSON_URL_URLNAME \
|
||||||
|
PREVIEW_ARTIST_PERSON_URL_URLLINK
|
||||||
|
|
||||||
|
PREVIEW_ARTIST_GROUP_FMT="${PREVIEW_ARTIST_GROUP_FMT:-"$PREVIEW_ARTIST_PERSON_FMT"}"
|
||||||
|
PREVIEW_ARTIST_GROUP_NAME="${PREVIEW_ARTIST_GROUP_NAME:-"$PREVIEW_ARTIST_PERSON_NAME"}"
|
||||||
|
PREVIEW_ARTIST_GROUP_SORTNAME="${PREVIEW_ARTIST_GROUP_SORTNAME:-"$PREVIEW_ARTIST_PERSON_SORTNAME"}"
|
||||||
|
PREVIEW_ARTIST_GROUP_BIO="${PREVIEW_ARTIST_GROUP_BIO:-"$PREVIEW_ARTIST_PERSON_BIO"}"
|
||||||
|
PREVIEW_ARTIST_GROUP_DISAMB="${PREVIEW_ARTIST_GROUP_DISAMB:-"$PREVIEW_ARTIST_PERSON_DISAMB"}"
|
||||||
|
PREVIEW_ARTIST_GROUP_ALIAS="${PREVIEW_ARTIST_GROUP_ALIAS:-"$PREVIEW_ARTIST_PERSON_ALIAS"}"
|
||||||
|
PREVIEW_ARTIST_GROUP_ALIAS_JOIN="${PREVIEW_ARTIST_GROUP_ALIAS_JOIN:-"$PREVIEW_ARTIST_PERSON_ALIAS_JOIN"}"
|
||||||
|
PREVIEW_ARTIST_GROUP_START="${PREVIEW_ARTIST_GROUP_START:-"✂️ Founded: %s\n"}"
|
||||||
|
PREVIEW_ARTIST_GROUP_START_FMT="${PREVIEW_ARTIST_GROUP_START_FMT:-"$PREVIEW_ARTIST_PERSON_START_FMT"}"
|
||||||
|
PREVIEW_ARTIST_GROUP_START_STARTDATE="${PREVIEW_ARTIST_GROUP_START_STARTDATE:-"$PREVIEW_ARTIST_PERSON_START_STARTDATE"}"
|
||||||
|
PREVIEW_ARTIST_GROUP_START_STARTPLACE="${PREVIEW_ARTIST_GROUP_START_STARTPLACE:-"$PREVIEW_ARTIST_PERSON_START_STARTPLACE"}"
|
||||||
|
PREVIEW_ARTIST_GROUP_END="${PREVIEW_ARTIST_GROUP_END:-"🛑 Dissolved: %s\n"}"
|
||||||
|
PREVIEW_ARTIST_GROUP_END_FMT="${PREVIEW_ARTIST_GROUP_END_FMT:-"$PREVIEW_ARTIST_PERSON_END_FMT"}"
|
||||||
|
PREVIEW_ARTIST_GROUP_END_ENDDATE="${PREVIEW_ARTIST_GROUP_END_ENDDATE:-"$PREVIEW_ARTIST_PERSON_END_ENDDATE"}"
|
||||||
|
PREVIEW_ARTIST_GROUP_END_ENDPLACE="${PREVIEW_ARTIST_GROUP_END_ENDPLACE:-"$PREVIEW_ARTIST_PERSON_END_ENDPLACE"}"
|
||||||
|
PREVIEW_ARTIST_GROUP_URL="${PREVIEW_ARTIST_GROUP_URL:-"$PREVIEW_ARTIST_PERSON_URL"}"
|
||||||
|
PREVIEW_ARTIST_GROUP_URL_JOIN="${PREVIEW_ARTIST_GROUP_URL_JOIN:-"$PREVIEW_ARTIST_PERSON_URL_JOIN"}"
|
||||||
|
PREVIEW_ARTIST_GROUP_URL_FMT="${PREVIEW_ARTIST_GROUP_URL_FMT:-"$PREVIEW_ARTIST_PERSON_URL_FMT"}"
|
||||||
|
PREVIEW_ARTIST_GROUP_URL_URLINDEX="${PREVIEW_ARTIST_GROUP_URL_URLINDEX:-"$PREVIEW_ARTIST_PERSON_URL_URLINDEX"}"
|
||||||
|
PREVIEW_ARTIST_GROUP_URL_URLNAME="${PREVIEW_ARTIST_GROUP_URL_URLNAME:-"$PREVIEW_ARTIST_PERSON_URL_URLNAME"}"
|
||||||
|
PREVIEW_ARTIST_GROUP_URL_URLLINK="${PREVIEW_ARTIST_GROUP_URL_URLLINK:-"$PREVIEW_ARTIST_PERSON_URL_URLLINK"}"
|
||||||
|
export PREVIEW_ARTIST_GROUP_FMT PREVIEW_ARTIST_GROUP_NAME \
|
||||||
|
PREVIEW_ARTIST_GROUP_SORTNAME PREVIEW_ARTIST_GROUP_BIO \
|
||||||
|
PREVIEW_ARTIST_GROUP_DISAMB PREVIEW_ARTIST_GROUP_ALIAS \
|
||||||
|
PREVIEW_ARTIST_GROUP_ALIAS_JOIN PREVIEW_ARTIST_GROUP_START \
|
||||||
|
PREVIEW_ARTIST_GROUP_START_FMT PREVIEW_ARTIST_GROUP_START_STARTDATE \
|
||||||
|
PREVIEW_ARTIST_GROUP_START_STARTPLACE PREVIEW_ARTIST_GROUP_END \
|
||||||
|
PREVIEW_ARTIST_GROUP_END_FMT PREVIEW_ARTIST_GROUP_END_ENDDATE \
|
||||||
|
PREVIEW_ARTIST_GROUP_END_ENDPLACE PREVIEW_ARTIST_GROUP_URL \
|
||||||
|
PREVIEW_ARTIST_GROUP_URL_JOIN PREVIEW_ARTIST_GROUP_URL_FMT \
|
||||||
|
PREVIEW_ARTIST_GROUP_URL_URLINDEX PREVIEW_ARTIST_GROUP_URL_URLNAME \
|
||||||
|
PREVIEW_ARTIST_GROUP_URL_URLLINK
|
||||||
|
|
||||||
|
# Keybinding themes
|
||||||
|
# =================
|
||||||
|
# Format keybinding group
|
||||||
|
KBF_GROUP="${KBF_GROUP:-"${UNDERLINE}${CKB}%s${OFF}"}"
|
||||||
|
# Format key
|
||||||
|
KBF_KEY="${KBF_KEY:-"${BOLD}${CKB}%s${OFF}"}"
|
||||||
|
# Format description
|
||||||
|
KBF_DESC="${KBF_DESC:-"${CKB}%s${OFF}"}"
|
||||||
|
export KBF_GROUP KBF_KEY KBF_DESC
|
||||||
|
|
||||||
|
# Playlist title and playlist store
|
||||||
|
# =================================
|
||||||
|
TITLE_PLYLST="${TITLE_PLYLST:-" 🎶 ${CARTIST}Playlist${OFF} "}"
|
||||||
|
TITLE_PLYLST_STORE="${TITLE_PLYLST_STORE:-" 🎶 ${CARTIST}Stored Playlists${OFF} "}"
|
||||||
|
# In the following %f is the file name
|
||||||
|
PLYSTORE_PLAYLIST="${PLYSTORE_PLAYLIST:-"🎼 ${CPURPLE}%f${OFF}"}"
|
||||||
|
export TITLE_PLYLST TITLE_PLYLST_STORE PLYSTORE_PLAYLIST
|
||||||
|
|
||||||
|
# Lyrics
|
||||||
|
# ======
|
||||||
|
LYRICS_NO_LYRICS="${LYRICS_NO_LYRICS:-"(no lyrics)"}"
|
||||||
|
export LYRICS_NO_LYRICS
|
||||||
|
|
||||||
|
export THEME_LOADED=1
|
||||||
|
fi
|
||||||
|
|||||||
@@ -55,5 +55,25 @@ if [ ! "${TOOLS_LOADED:-}" ]; then
|
|||||||
command -v "xsel" >/dev/null && CLIP="xsel" || CLIP="true"
|
command -v "xsel" >/dev/null && CLIP="xsel" || CLIP="true"
|
||||||
export CLIP
|
export CLIP
|
||||||
|
|
||||||
|
# Detect external editor
|
||||||
|
editor="${EDITOR:-vi}"
|
||||||
|
if command -v "$editor" >/dev/null; then
|
||||||
|
if command -v "kitty" >/dev/null; then
|
||||||
|
extedit=$(printf "kitty %s" "$editor")
|
||||||
|
elif command -v "x-terminal-emulator" >/dev/null; then
|
||||||
|
extedit=$(printf "x-terminal-emulator -e %s" "$editor")
|
||||||
|
elif command -v "gnome-terminal" >/dev/null; then
|
||||||
|
extedit=$(printf "gnome-terminal -- %s" "$editor")
|
||||||
|
elif command -v "xterm" >/dev/null; then
|
||||||
|
extedit=$(printf "xterm -e %s" "$editor")
|
||||||
|
else
|
||||||
|
extedit=""
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
extedit=""
|
||||||
|
fi
|
||||||
|
EXTERNALEDIT="${EXTERNALEDIT:-"$extedit"}"
|
||||||
|
export EXTERNALEDIT
|
||||||
|
|
||||||
export TOOLS_LOADED=1
|
export TOOLS_LOADED=1
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user