ncspot is a ncurses Spotify client written in Rust using librespot.

Overview

logo

ncspot

Crates.io Gitter Build

Packaging status

ncspot ncspot

ncspot is a ncurses Spotify client written in Rust using librespot. It is heavily inspired by ncurses MPD clients, such as ncmpc. My motivation was to provide a simple and resource friendly alternative to the official client as well as to support platforms that currently don't have a Spotify client, such as the *BSDs.

Search

Table of Contents

Resource Footprint Comparison

Measured using ps_mem on Linux during playback:

Client Private Memory Shared Memory Total
ncspot 22.1 MiB 24.1 MiB 46.2 MiB
Spotify 407.3 MiB 592.7 MiB 1000.0 MiB

Installation

On macOS

ncspot is available via Homebrew:

brew install ncspot

On Windows

ncspot is available via Scoop:

scoop install ncspot

On Linux

Requirements:

  • Rust
  • Python 3 (needed for building rust-xcb dependency)
  • libpulse-dev (or portaudio-dev, if you want to use the PortAudio backend)
  • libncurses-dev and libssl-dev
  • libdbus-1-dev
  • libxcb + development headers (for clipboard access)
  • pkg-config
  • A Spotify premium account

On Debian based systems you need following packages for development headers:

sudo apt install libncursesw5-dev libdbus-1-dev libpulse-dev libssl-dev libxcb1-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev

For Fedora, these dependencies are required:

dnf install pulseaudio-libs-devel libxcb-devel openssl-devel ncurses-devel dbus-devel

Building a Debian Package

You can use cargo-deb create in order to build a Debian package from source. Install it with:

cargo install cargo-deb

Then you can build a Debian package with:

cargo deb

You can find it under target/debian.

Build

Install the latest ncspot release using:

cargo install ncspot

Or build it yourself using:

cargo build --release

# NB: add these flags on Windows
cargo build --release --no-default-features --features rodio_backend,cursive/pancurses-backend
  • Both approaches require a working Rust installation.

  • For debugging, you can pass a debug log filename and log stderr to a file, e.g. :

    RUST_BACKTRACE=full cargo run -- -d debug.log 2> stderr.log

Audio Backends

By default ncspot is built using the PulseAudio backend. To make it use the PortAudio backend (e.g. for *BSD or macOS) or Rodio backend (e.g. for Windows), you need to recompile ncspot with the respective features:

# PortAudio (BSD/macOS)
cargo run --no-default-features --features portaudio_backend,cursive/pancurses-backend

# Rodio (Windows)
cargo run --no-default-features --features rodio_backend,cursive/pancurses-backend

Key Bindings

The keybindings listed below are configured by default. Additionally, if you run ncspot with MPRIS support, you may be able to use media keys to control playback depending on your desktop environment settings. Have a look at the configuration section if you want to set custom bindings.

Navigation

Key Command
? Show help screen.
F1 Queue (See specific commands).
F2 Search.
F3 Library (See specific commands).
F8 Album Art (if compiled with the cover feature).
/ Open a Vim-like search bar (See specific commands).
: Open a Vim-like command prompt (See specific commands).
Escape Close Vim-like search bar or command prompt.
Q Quit ncspot.

Playback

Key Command
Return Play track or playlist.
Space Queue track or playlist.
. Play the selected item after the currently playing track.
P Move to the currently playing track in the queue.
S Save the currently playing track to your library.
D Remove the currently playing track from your library.
Shift+P Toggle playback (i.e. Play/Pause).
Shift+S Stop playback.
Shift+U Update the library cache (tracks, artists, albums, playlists).
< Play the previous track.
> Play the next track.
F Seek forward.
Shift+F Seek forward with a 10-second step.
B Seek backwards.
Shift+B Seek backwards with a 10-second step.
- Decrease volume by 1.
+ Increase volume by 1.
[ Decrease volume by 5.
] Increase volume by 5.
R Toggle Repeat mode.
Z Toggle Shuffle state.

Context Menus

Key Command
O Open a detail view or context for the selected item.
Shift+O Open a context menu for the currently playing track.
A Open the album view for the selected item.
Shift+A Open the artist view for the selected item.
M Open the recommendations view for the selected item.
Shift+M Open the recommendations view for the currently playing track.
Ctrl+V Open the context menu for a Spotify link in your clipboard.
Backspace Close the current view.

When pressing O:

  • If the selected item is not a track, it opens a detail view.
  • If the selected item is a track, it opens a context menu with:
    • "Show Artist"
    • "Show Album"
    • "Share"
    • "Add to playlist"
    • "Similar tracks"

Sharing

Key Command
X Copy a shareable URL of the currently selected item to the system clipboard.
Shift+X Copy a shareable URL of the currently playing track to the system clipboard.

Queue

Key Command
C Clear the entire queue.
D Delete the currently selected track.
Ctrl+S Delete the currently selected track.

Library

Key Command
D Delete the currently selected playlist.

Vim-Like Search Bar

Key Command
n Previous search occurrence.
N Next search occurrence.

Vim-Like Commands

You can open a Vim-style command prompt using :, and close it at any time with Escape.

The following is an abridged list of commonly-used commands. For the full list, see source code.

Command Action
help Show current key bindings.
quit
Aliases: q, x
Quit ncspot.
logout Remove any cached credentials from disk and quit ncspot.
playpause
Aliases: pause, toggleplay, toggleplayback
Toggle playback.
stop Stop playback.
seek [+|-] Seek to the specified position, or seek relative to current position by prepending +/-. Supports mixing time units (e.g. seek 1m42s). Default unit is millisecond.
repeat [repeat_mode]
Aliases: loop
Set repeat mode. Omit repeat_mode argument to step through the available modes.
shuffle [on|off] Enable or disable shuffle. Omit argument to toggle.
previous Play previous track.
next Play next track.
focus Switch to a screen.
search Search a song.
clear Clear playlist.
share Copies a shareable URL of the item to the system clipboard.
newplaylist Create new playlist with name name.
sort [sort_direction] Sort a playlist by sort_key in direction sort_direction. Default direction is ascending.
exec Executes a command in the system shell. Be aware that command output is printed to the terminal, so redirection to /dev/null e.g. by appending 2> /dev/null may be necessary.
  • Supported repeat_mode are:
    • list | playlist | queue
    • track | once | single
    • none | off
  • Supported item are:
    • selected: Selected item.
    • current: Current song.
  • Supported sort_key are:
    • title
    • album
    • artist
    • duration
    • added
  • Supported sort_direction are:
    • a | asc | ascending
    • d | desc | descending

Configuration

Configuration is saved to ~/.config/ncspot/config.toml (or %AppData%\ncspot\config.toml on Windows). To reload the configuration during runtime use the command prompt by typing :reload.

Possible configuration values are:

Name Description Possible values Default
command_key Key to open command line Single character :
initial_screen Screen to show after startup "library", "search", "queue", "cover"1 "library"
use_nerdfont Turn nerdfont glyphs on/off true, false false
flip_status_indicators Reverse play/pause icon meaning2 true, false false
backend Audio backend to use String 3
backend_device Audio device to configure the backend String
audio_cache Enable caching of audio files true, false true
audio_cache_size Maximum size of audio cache in MiB Number
volnorm Enable volume normalization true, false false
volnorm_pregain Normalization pregain to apply in dB (if enabled) Number 0.0
default_keybindings Enable default keybindings true, false false
notify Enable desktop notifications true, false false
bitrate Audio bitrate to use for streaming 96, 160, 320 320
album_column Show album column for tracks true, false true
gapless Enable gapless playback true, false true
shuffle Set default shuffle state true, false false
repeat Set default repeat mode off, track, playlist off
playback_state Set default playback state "Stopped", "Paused", "Playing", "Default" "Paused"
library_tabs Tabs to show in library screen Array of tracks, albums, artists, playlists, podcasts All tabs
[track_format] Set active fields shown in Library/Queue views See track formatting
[theme] Custom theme See custom theme
[keybindings] Custom keybindings See custom keybindings

Custom Keybindings

Keybindings can be configured in [keybindings] section in config.toml, e.g. as such:

[keybindings]
"Shift+i" = "seek +10000"

Proxy

ncspot will respect system proxy settings defined via the http_proxy environment variable.

Theming

Theme generator by @vaarad.

The color palette can be modified in the configuration. For instance, to have ncspot match Spotify's official client, you can add the following entries to the configuration file:

[theme]
background = "black"
primary = "light white"
secondary = "light black"
title = "green"
playing = "green"
playing_selected = "light green"
playing_bg = "black"
highlight = "light white"
highlight_bg = "#484848"
error = "light white"
error_bg = "red"
statusbar = "black"
statusbar_progress = "green"
statusbar_bg = "green"
cmdline = "light white"
cmdline_bg = "black"
search_match = "light red"

More examples can be found in this pull request.

Track Formatting

It's possible to customize which fields are shown in Queue/Library views. If you don't define center for example, the default value will be used. Available options for tracks: %artists, %title, %album, %saved, %duration Default configuration:

[track_format]
left = "%artists - %title"
center = "%album"
right = "%saved %duration"
Examples: (Click to show/hide)

Example 1 - Show only album name and track name after it:

[track_format]
left = "%album"
center = "%title"
right = ""

Example 2 - Show track title before artists, and don't show album at all:

[track_format]
left = "%title - %artists"
center = ""

Example 3 - Show everything as default, but hide saved status and track length:

[track_format]
right = ""

Example 4 - Show everything as default, except show title before artists:

[track_format]
left = "%title - %artists"

Example 5 - Show saved status and duration first, followed by track title and artists, with the album last:

[track_format]
left = "|%saved| %duration | %title - %artists"
center = ""
right = "%album"

Cover Drawing

When compiled with the cover feature, ncspot can draw the album art of the current track in a dedicated view (:focus cover or F8 by default) using Überzug. For more information on installation and terminal compatibility, consult that repository.

To allow scaling the album art up beyond its resolution (640x640 for Spotify covers), use the config key cover_max_scale. This is especially useful for HiDPI displays:

cover_max_scale = 2

Authentication

ncspot prompts for a Spotify username and password on first launch, uses this to generate an OAuth token, and stores it to disk.

The credentials are stored in ~/.cache/ncspot/librespot/credentials.json (unless the base path has been changed with the --basepath option).

The :logout command can be used to programmatically remove cached credentials (see Vim-Like Commands above).

Footnotes

  1. If enabled.

  2. By default the statusbar will show a play icon when a track is playing and a pause icon when playback is stopped. If this setting is enabled, the behavior is reversed.

  3. Run ncspot -h for a list of devices.

Comments
  • Cannot create session: Connection refused (os error 111)

    Cannot create session: Connection refused (os error 111)

    Describe the bug A clear and concise description of what the bug is. After launching ncspot login prompt pops up, even though I was logged in previously, and when I try to log in I receive this error: image

    To Reproduce Steps to reproduce the behavior:

    1. Launch ncspot

    Expected behavior Successful login

    System (please complete the following information):

    • OS: Arch Linux 5.12.4
    • Terminal: Alacritty
    • Version: 0.7.1
    • Installed from: AUR

    Backtrace/Debug log Instructions on how to capture debug logs: https://github.com/hrkfdn/ncspot#usage

    [2021-05-22][21:49:45] [ncspot] [INFO] Using cached credentials
    [2021-05-22][21:49:45] [ncspot::spotify] [DEBUG] No HTTP proxy set
    [2021-05-22][21:49:45] [librespot_core::session] [INFO] Connecting to AP "ap.spotify.com:443"
    [2021-05-22][21:49:45] [mio::poll] [TRACE] registering event source with poller: token=Token(0), interests=READABLE | WRITABLE
    [2021-05-22][21:49:45] [mio::poll] [TRACE] deregistering event source from poller
    [2021-05-22][21:49:46] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:46] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:46] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:47] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:47] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:47] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:47] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:47] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:47] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:47] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:47] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:47] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:47] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:47] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:47] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:47] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:47] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:47] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:47] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:47] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:47] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:48] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:48] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:48] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:48] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:48] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:48] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:48] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:48] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:48] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:48] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:48] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:48] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:48] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:48] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:48] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:48] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:48] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:48] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:49] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:49] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:49] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:49] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:49] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:49] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:49] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:49] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:49] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:53] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:53] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:53] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:54] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:54] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:54] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:54] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:54] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:54] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:55] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:55] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:55] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:55] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:55] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:55] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:56] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:49:56] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:56] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:49:56] [ncspot::spotify] [DEBUG] No HTTP proxy set
    [2021-05-22][21:49:56] [librespot_core::session] [INFO] Connecting to AP "ap.spotify.com:443"
    [2021-05-22][21:49:56] [mio::poll] [TRACE] registering event source with poller: token=Token(16777216), interests=READABLE | WRITABLE
    [2021-05-22][21:49:56] [mio::poll] [TRACE] deregistering event source from poller
    [2021-05-22][21:50:57] [ncspot] [INFO] Using cached credentials
    [2021-05-22][21:50:57] [ncspot::spotify] [DEBUG] No HTTP proxy set
    [2021-05-22][21:50:57] [librespot_core::session] [INFO] Connecting to AP "ap.spotify.com:443"
    [2021-05-22][21:50:57] [mio::poll] [TRACE] registering event source with poller: token=Token(0), interests=READABLE | WRITABLE
    [2021-05-22][21:50:57] [mio::poll] [TRACE] deregistering event source from poller
    [2021-05-22][21:50:59] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:50:59] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:50:59] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:50:59] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:50:59] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:50:59] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:07] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:08] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:09] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:51:09] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:09] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:09] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:51:09] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:09] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:10] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:51:10] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:10] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:51:10] [ncspot::spotify] [DEBUG] No HTTP proxy set
    [2021-05-22][21:51:10] [librespot_core::session] [INFO] Connecting to AP "ap.spotify.com:443"
    [2021-05-22][21:51:10] [mio::poll] [TRACE] registering event source with poller: token=Token(16777216), interests=READABLE | WRITABLE
    [2021-05-22][21:51:10] [mio::poll] [TRACE] deregistering event source from poller
    [2021-05-22][21:52:55] [ncspot] [INFO] Using cached credentials
    [2021-05-22][21:52:55] [ncspot::spotify] [DEBUG] No HTTP proxy set
    [2021-05-22][21:52:55] [librespot_core::session] [INFO] Connecting to AP "ap.spotify.com:443"
    [2021-05-22][21:52:55] [mio::poll] [TRACE] registering event source with poller: token=Token(0), interests=READABLE | WRITABLE
    [2021-05-22][21:52:55] [mio::poll] [TRACE] deregistering event source from poller
    [2021-05-22][21:53:03] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:53:03] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:03] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:04] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:53:04] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:04] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:04] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:53:04] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:04] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:04] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:53:04] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:04] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:04] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:53:04] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:04] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:04] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:53:04] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:04] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:04] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:53:04] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:04] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:04] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:53:04] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:04] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:05] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:06] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:53:06] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:06] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:06] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:53:06] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:06] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:07] [cursive_core::views::list_view] [DEBUG] Available: 18
    [2021-05-22][21:53:07] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:07] [cursive_core::views::list_view] [DEBUG] Offset: 9
    [2021-05-22][21:53:07] [ncspot::spotify] [DEBUG] No HTTP proxy set
    [2021-05-22][21:53:07] [librespot_core::session] [INFO] Connecting to AP "ap.spotify.com:443"
    [2021-05-22][21:53:07] [mio::poll] [TRACE] registering event source with poller: token=Token(16777216), interests=READABLE | WRITABLE
    [2021-05-22][21:53:07] [mio::poll] [TRACE] deregistering event source from poller
    
    bug 
    opened by gbaranski 26
  • Add configurable theme

    Add configurable theme

    Adds the ability to change the theme via the config file. I mostly avoided using Cursive's ColorStyle presets because they're a bit inflexible (for example highlight() forces you to use a highlight color that is sufficiently different from the background color, since that's used as the foreground), but I tried to use the existing PaletteColor enum for compatibility. For some of the more specific UI elements (error, status bar, etc.) I added custom colors.

    New default (fairly close to old default):

    A style closer to the official Spotify client:

    [theme]
    background = "black"
    primary = "light white"
    secondary = "light black"
    title = "green"
    playing = "green"
    playing_bg = "black"
    highlight = "light white"
    highlight_bg = "#484848"
    error = "light white"
    error_bg = "red"
    statusbar = "black"
    statusbar_progress = "green"
    statusbar_bg = "green"
    cmdline = "light white"
    cmdline_bg = "black"
    

    You can even use a light theme if you're a freak:

    [theme]
    background = "light white"
    primary = "black"
    secondary = "blue"
    title = "red"
    playing = "blue"
    playing_bg = "light white"
    highlight = "black"
    highlight_bg = "light blue"
    error = "light white"
    error_bg = "red"
    statusbar_progress = "blue"
    statusbar = "black"
    statusbar_bg = "light white"
    cmdline = "black"
    cmdline_bg = "light white"
    
    opened by KoffeinFlummi 22
  • Thread Error

    Thread Error

    Using on Ubuntu.18.04 Usually after sleep, I get following error after one song

    thread '<unnamed>' panicked at 'could not send no-op event to cursive: "SendError(..)"', src/events.rs:41:9

    opened by harpreetsb 18
  • Added possibility to turn on/off shuffle using MPRIS

    Added possibility to turn on/off shuffle using MPRIS

    Hello, I added shuffle support for MPRIS. Solves #317.

    For example using playerctl: playerctl -p ncspot shuffle on -> Turns shuffle on playerctl -p ncspot shuffle off -> Turns shuffle off

    However I'm facing one problem that I can't figure out. After adding these changes, running playerctl -p ncspot shuffle always returns "Off" regardless of the actual shuffle state. Without these changes it functions as expected, and returns "On" or "Off" depending on the shuffle state. I'd imagine it's probably a simple fix but I'm still a Rust newbie so I can't quite figure it out on my own :/

    opened by Bettehem 17
  • Add sharing functionality

    Add sharing functionality

    I do a lot of sharing of Spotify songs, and to make this my main client I need the feature. This implementation uses the key-bind m and the command share to copy the currently playing song to the system clipboard.

    Creating a clipboard context for each time a share happens isn't great, but because sharing is (generally) a rare occurrence.

    The new library is used by Mozilla in Servo so shouldn't be an issue to include.

    Is copying the currently playing song the desired functionality, or would it be better to share the currently selected song? Maybe sharing the currently playing song only when used with a shift modifier. You could then modify the command to be either share selected or share current.

    opened by Herbstein 17
  • Persist runtime state

    Persist runtime state

    Persist runtime state, e.g.

    • [x] track queue
    • [x] playback mode (shuffle, repeat, etc.)
    • [x] volume
    • [ ] sorting orders for playlist
    • [x] add config values to override stored state for shuffle, repeat and volume

    and reload it upon restart

    enhancement 
    opened by hrkfdn 16
  • Last.fm Scrobbling (and now-playing) Support

    Last.fm Scrobbling (and now-playing) Support

    I thought Spotify now implements scrobbling at an account level, independent of device or client, but maybe I'm wrong, as playing with ncspot (which I'm very excited about, thank you!) doesn't seem to result in scrobbles or now-playing information available to Last.fm.

    I don't personally care if ncspot implements scrobbling internally or finds a way to get Spotify servers to do so, but I really need a music player to scrobble one way or another for me to use it.

    Arch Linux, installed from AUR ncspot-git 0.0.0.98.3d385af-1

    Thanks for this project!

    enhancement 
    opened by AndydeCleyre 16
  • ncspot window looking corrupted/wrong

    ncspot window looking corrupted/wrong

    Describe the bug So, normally ncspot looks like normal ncurses, clean and straightforward. However, my terminal (Konsole) did not like that.

    To Reproduce Steps to reproduce the behavior:

    1. Open ncspot

    Expected behavior I expected it to not look corrupted-ish, and I know how it's supposed to look like, I had it installed on Debian and it looked just fine, but with Arch Linux, everything looks.. wrong.

    Screenshots image i dont think thats how its supposed to look like

    System (please complete the following information):

    • OS: Arch Linux
    • Terminal: Konsole
    • Version: 0.7.3
    • Installed from: cargo (AUR too, both ncspot and ncspot-git looked like this)

    Backtrace/Debug log stderr.log

    error: could not find `Cargo.toml` in `/home/atlas` or any parent directory
    

    To debug crashes a backtrace is very helpful. Make sure you run a debug build of ncspot, e.g. by running the command mentioned in the link above. (I don't quite think this is going to be very useful...)

    Additional context It's most likely an issue with Konsole. Or Arch.

    bug 
    opened by AtlasC0R3 15
  • Failing to build on NetBSD

    Failing to build on NetBSD

    Hopefully someone running ncspot on OpenBSD can help me here. I'm really keen to get this working on my NetBSD machine but I get a build error:

    $ cargo run --no-default-features --features portaudio_backend,cursive/pancurses-backend 
    ...
    error: failed to run custom build command for `ncurses v5.99.0`
    
    Caused by:
      process didn't exit successfully: `/home/dave/Downloads/ncspot/target/debug/build/ncurses-cca56809b8b206f2/build-script-build` (exit code: 101)
    --- stdout
    cargo:rerun-if-env-changed=PKG_CONFIG_PATH
    cargo:rustc-link-lib=ncursesw
    OPT_LEVEL = Some("0")
    TARGET = Some("x86_64-unknown-netbsd")
    HOST = Some("x86_64-unknown-netbsd")
    CC_x86_64-unknown-netbsd = None
    CC_x86_64_unknown_netbsd = None
    HOST_CC = None
    CC = None
    CFLAGS_x86_64-unknown-netbsd = None
    CFLAGS_x86_64_unknown_netbsd = None
    HOST_CFLAGS = None
    CFLAGS = None
    CRATE_CC_NO_DEFAULTS = None
    DEBUG = Some("true")
    CARGO_CFG_TARGET_FEATURE = Some("fxsr,sse,sse2")
    
    --- stderr
    /home/dave/Downloads/ncspot/target/debug/build/ncurses-c07513f36080cdf7/out/chtype_size.c:6:10: fatal error: ncurses.h: No such file or directory
     #include <ncurses.h>
              ^~~~~~~~~~~
    compilation terminated.
    thread 'main' panicked at 'assertion failed: command.status().expect("compilation failed").success()', /home/dave/.cargo/registry/src/github.com-1ecc6299db9ec823/ncurses-5.99.0/build.rs:105:5
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    
    warning: build failed, waiting for other jobs to finish...
    error: build failed
    

    Poraudio & ncurses are installed

    $ pkgin list | grep portaudio                                                            
    portaudio-190600.20161030nb5 Portable cross-platform audio API
    $ pkgin list | grep ncurses                                                              
    ncurses-6.2nb2       CRT screen handling and optimization package
    
    opened by pfr-dev 15
  • No sound after snap package installation

    No sound after snap package installation

    Hi!

    I am really hyped by your work, but after the installation of the package via snap, no sound can be heard when using your app! I know that you are not the maintainer of the snap package but maybe there is a way to contact the person in charge of it? I really want to use it ^^

    Thanks in advance.

    opened by BlueskyFR 14
  • MPRIS signal PropertiesChanged is not triggered

    MPRIS signal PropertiesChanged is not triggered

    Hi,

    I am the developer behind a generic scrobbling daemon for linux, called mpris-scrobbler and I had a bug report from a user involving ncspot[1].

    The issue boiled down to ncspot's MPRIS implementation not triggering the /org/mpris/MediaPlayer2/org.freedesktop.DBus.Properties/PropertiesChanged when track or play status change.

    I'm not sure if this is a problem of the underlying library or the player must enable this signal specifically, but it would be great if someone could give it a look.

    Thank you.

    [1] https://github.com/mariusor/mpris-scrobbler/issues/66

    bug 
    opened by mariusor 14
  • Bump notify-rust from 4.6.0 to 4.7.0

    Bump notify-rust from 4.6.0 to 4.7.0

    Bumps notify-rust from 4.6.0 to 4.7.0.

    Changelog

    Sourced from notify-rust's changelog.

    v4.7.0 (2023-01-08)

    Features

    • Accept durations as timeout arguments (3ab191a)
    • implement FromStr for Timeout (b87b859)

    Fixes

    • deps: update rust crate zbus to 3.6 (89779e8)
    Commits
    • e052e40 chore: bump version
    • 79a4d62 docs: describe edgecases when passing a duration as timeout
    • 940a54b Merge pull request #172 from nicos68/duration
    • 67da0ea Merge branch 'main' into duration
    • a433964 chore: update maintenance badge
    • 3ab191a feat: Accept durations as timeout arguments
    • de6495c chore: fix build badge
    • 65516e8 Merge pull request #165 from hoodie/renovate/zbus-3.x
    • 89779e8 fix(deps): update rust crate zbus to 3.6
    • e45ddb7 Merge pull request #169 from rnestler/add-form-str-impl-for-timeout
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Bump dbus from 0.9.6 to 0.9.7

    Bump dbus from 0.9.6 to 0.9.7

    Bumps dbus from 0.9.6 to 0.9.7.

    Commits
    • ad81b09 Release libdbus 0.2.3, dbus 0.9.7
    • ecb379d Merge pull request #418 from diwic/31-ownedfd
    • 65d0a44 dbus: Remove io-lifetimes feature, add stdfd feature
    • d913c60 crossroads: Fixup introspection of children
    • bf1e745 crossroads: Fixup context lost in GetManagedObjects
    • 7fe3b49 crossroads: Test multiple objects in async-property ObjectManager test
    • 007b040 crossroads: Fixup another async path where the context got lost
    • a346ee3 crossroads: Extend testing to cover async multi-interface GetAll
    • 76cb265 crossroads: Do not output descendants on introspection
    • e025d99 Merge pull request #411 from landhb/ci_upgrades
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Bump tokio from 1.23.0 to 1.24.1

    Bump tokio from 1.23.0 to 1.24.1

    Bumps tokio from 1.23.0 to 1.24.1.

    Release notes

    Sourced from tokio's releases.

    Tokio v1.24.1

    This release fixes a compilation failure on targets without AtomicU64 when using rustc older than 1.63. (#5356)

    #5356: tokio-rs/tokio#5356

    Tokio v1.24.0

    The highlight of this release is the reduction of lock contention for all I/O operations (#5300). We have received reports of up to a 20% improvement in CPU utilization and increased throughput for real-world I/O heavy applications.

    Fixed

    • rt: improve native AtomicU64 support detection (#5284)

    Added

    • rt: add configuration option for max number of I/O events polled from the OS per tick (#5186)
    • rt: add an environment variable for configuring the default number of worker threads per runtime instance (#4250)

    Changed

    • sync: reduce MPSC channel stack usage (#5294)
    • io: reduce lock contention in I/O operations (#5300)
    • fs: speed up read_dir() by chunking operations (#5309)
    • rt: use internal ThreadId implementation (#5329)
    • test: don't auto-advance time when a spawn_blocking task is running (#5115)

    #5186: tokio-rs/tokio#5186 #5294: tokio-rs/tokio#5294 #5284: tokio-rs/tokio#5284 #4250: tokio-rs/tokio#4250 #5300: tokio-rs/tokio#5300 #5329: tokio-rs/tokio#5329 #5115: tokio-rs/tokio#5115 #5309: tokio-rs/tokio#5309

    Tokio v1.23.1

    This release forward ports changes from 1.18.4.

    Fixed

    • net: fix Windows named pipe server builder to maintain option when toggling pipe mode (#5336).

    #5336: tokio-rs/tokio#5336

    Commits
    • 31c7e82 chore: prepare Tokio v1.24.1 (#5357)
    • 8d8db27 tokio: add load and compare_exchange_weak to loom StaticAtomicU64 (#5356)
    • dfe252d chore: prepare Tokio v1.24.0 release (#5353)
    • 21b233f test: bump version of async-stream (#5347)
    • 7299304 Merge branch 'tokio-1.23.x' into master
    • 1a997ff chore: prepare Tokio v1.23.1 release
    • a8fe333 Merge branch 'tokio-1.20.x' into tokio-1.23.x
    • ba81945 chore: prepare Tokio 1.20.3 release
    • 763bdc9 ci: run WASI tasks using latest Rust
    • 9f98535 Merge remote-tracking branch 'origin/tokio-1.18.x' into fix-named-pipes-1.20
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Allow search to include results with special characters

    Allow search to include results with special characters

    Is your feature request related to a problem? Please describe. Right now, when searching for text that includes special characters on top of a normal character (é, ç, à, ë, ê...), the results don't include letters with those special characters. It would be nice if this would be possible. It could be behind a configuration option for people who like to search very specifically.

    Describe the solution you'd like A search for hello should also show hëllo, hêllo, héllo...

    enhancement 
    opened by ThomasFrans 0
  • Implement unsave command

    Implement unsave command

    We can save the currently playing track via the Command::Save implementation, but there is no unsave track command. Instead, we implement toggle logic as part of the TUI.

    Describe the solution you'd like With an unsave command, we'll be able to unsave a track via the newly implemented unix socket IPC.

    Describe alternatives you've considered Instrumenting the interface via IPC.

    enhancement 
    opened by deed02392 1
  • login not working on ubuntu wsl

    login not working on ubuntu wsl

    Describe the bug login not working. Double checked password and user for premium account on browser and standalone app.

    To Reproduce Steps to reproduce the behavior:

    1. install ncspot
    2. start ncspot
    3. fill in credentials dialog
    4. wait for some time, get error

    Expected behavior expected to login and start listening music

    Screenshots

    image

    System (please complete the following information):

    • OS: windows 10, WSL2
    • Terminal: Windows terminal
    • Version: ncspot 0.11.2
    • Installed from: snap
    bug 
    opened by joseazdir 1
Releases(v0.12.0)
Owner
Henrik Friedrichsen
Henrik Friedrichsen
Psst - Fast and multi-platform Spotify client with native GUI

Psst Fast Spotify client with native GUI, without Electron, built in Rust. Very early in development, lacking in features, stability, and general user

Jan Pochyla 7.2k Jan 2, 2023
Spotify for the terminal written in Rust 🚀

Spotify TUI A Spotify client for the terminal written in Rust. The terminal in the demo above is using the Rigel theme. Spotify TUI Installation Homeb

Alexander Keliris 14.1k Jan 1, 2023
A Spotify downloader written in rust, which does not require a premium account

DownOnSpot A Spotify downloader written in Rust Disclaimer DownOnSpot was not developed for piracy. It is meant to be used in compliance with DMCA, Se

oSumAtrIX 273 Jan 7, 2023
A spotify daemon

Spotifyd An open source Spotify client running as a UNIX daemon. Spotifyd streams music just like the official client, but is more lightweight and sup

null 8.4k Dec 31, 2022
🎧 a self-hosted Spotify → Discord music bot

Aoede is a Discord music bot that directly streams from Spotify to Discord. The only interface is Spotify itself. Note: a Spotify Premium account is c

Max Isom 159 Dec 29, 2022
code to connect + communicate with a Spotify Car Thing

spotify_carthing_bt A grab-bag of spotify car thing related hacks I'm working on. deskthing-rs A Rust port of https://github.com/relative/deskthing, w

Daniel Prilik 6 Dec 19, 2022
Effortlessly beautify your Spotify playlists with just a single, enchanting script 💫 🎵

harmonia harmonia, effortlessly beautify your Spotify playlists with just a single, enchanting script. ?? ?? HANDLE WITH LOVE: Since harmonia is bloss

Gülce 4 Jun 23, 2023
A command line application to organize Spotify playlists.

Sortify A command line application to organize Spotify playlists. Using Sortify, you can choose a playlist as the source playlist, and then have the o

Francisco Cunha 4 Aug 14, 2024
NekoMC (New Efficient Kitten-oriented MPRIS Client)

a waybar/general component for displaying current song data in bars like waybar and controling players using MPRIS

Insert5StarName 5 Mar 20, 2023
A library for constructing Groth-Sahai proofs using pre-built wrappers

Groth-Sahai Wrappers A Rust library containing wrappers that facilitate the construction of non-interactive witness-indistinguishable and zero-knowled

Jacob White 1 Mar 7, 2022
GStreamer plugin for speech to text using the Vosk Toolkit.

This project has moved upstream to the GStreamer Rust Plugins: https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/729 Vosk Speec

Rafael Carício 7 Apr 12, 2022
A music theory guide written in Rust.

Rust Music Theory A library and executable that provides programmatic implementation of the basis of the music theory. Table of Contents Overview Usag

Ozan Kaşıkçı 551 Dec 21, 2022
musify is a simple discord bot to play music within a voice channel, written in the rust programming language.

musify-rs musify is a simple discord bot to play music within a voice channel, written in the rust programming language. Features A simple song queue

NV6 5 Aug 14, 2022
Terminal Music Player written in Rust

Terminal Music Player written in Rust Listen to music freely as both in freedom and free of charge! Freedom: As time goes by, online service providers

null 376 Jan 3, 2023
Loopers is graphical live looper, written in Rust, designed for ease of use and rock-solid stability

Loopers Loopers is a graphical live looper, written in Rust, designed for ease of use and rock-solid stability. It can be used as a practice tool, com

Micah Wylde 81 Dec 29, 2022
Synthesizer IO - a synthesizer written in Rust.

Synthesizer IO Hopefully, this will become a synthesizer written in Rust. At the moment, it's experimental bits of technology toward that end. Running

Raph Levien 278 Dec 13, 2022
A drum machine written in Rust

rudiments rudiments is a step-sequencing drum machine that plays rhythm patterns using audio samples. Features 16-step programmable measures. Configur

Jonas Michel 141 Nov 23, 2022
VST2 frequency modulation synthesizer written in Rust

OctaSine VST2 frequency modulation synthesizer written in Rust. Official website with downloads OctaSine.com Audio examples SoundCloud Screenshots Lig

Joakim Frostegård 412 Dec 30, 2022
🎵 A super simple VST written in Rust

DigiDist This is a simple little VST plugin, developed in Rust using the vst2 crate. It doesn't sound particularly great, but it demonstrates just how

Joe Clay 34 May 29, 2022