@@ -13,9 +13,12 @@ travis-ci = { repository = "hrkfdn/ncspot", branch = "master" }
|
||||
maintenance = { status = "experimental" }
|
||||
|
||||
[dependencies]
|
||||
clap = "2.32.0"
|
||||
chrono = "0.4"
|
||||
crossbeam-channel = "0.3.8"
|
||||
directories = "1.0"
|
||||
failure = "0.1.3"
|
||||
fern = "0.5"
|
||||
futures = "0.1"
|
||||
log = "0.4.0"
|
||||
serde = "1.0"
|
||||
|
||||
@@ -25,7 +25,7 @@ future. Contributions welcome, but please be kind ;)
|
||||
|
||||
* Set your login credentials (see configuration)
|
||||
* Build using `cargo build --release`
|
||||
* The initial screen is the debug log. Press `F2` for the queue and `F3` to
|
||||
* The initial screen is the debug log. Press `F1` for the queue and `F2` to
|
||||
search for a track. More key bindings are described below.
|
||||
|
||||
### Key Bindings
|
||||
@@ -39,7 +39,6 @@ have them configurable.
|
||||
* `F3`: Playlists
|
||||
* `d` deletes the currently selected track
|
||||
* `c` clears the entire playlist
|
||||
* `F9`: Debug log
|
||||
* Tracks and playlists can be played using `Return` and queued using `Space`
|
||||
* `Shift-p` toggles playback of a track
|
||||
* `Shift-s` stops a track
|
||||
|
||||
@@ -129,17 +129,6 @@ impl CommandManager {
|
||||
);
|
||||
}
|
||||
|
||||
self.register(
|
||||
"log",
|
||||
Vec::new(),
|
||||
Box::new(move |s, _args| {
|
||||
s.call_on_id("main", |v: &mut Layout| {
|
||||
v.set_view("log");
|
||||
});
|
||||
Ok(None)
|
||||
}),
|
||||
);
|
||||
|
||||
self.register(
|
||||
"move",
|
||||
Vec::new(),
|
||||
@@ -365,7 +354,6 @@ impl CommandManager {
|
||||
kb.insert("F1".into(), "queue".into());
|
||||
kb.insert("F2".into(), "search".into());
|
||||
kb.insert("F3".into(), "playlists".into());
|
||||
kb.insert("F9".into(), "log".into());
|
||||
|
||||
kb.insert("Up".into(), "move up".into());
|
||||
kb.insert("Down".into(), "move down".into());
|
||||
|
||||
50
src/main.rs
50
src/main.rs
@@ -1,3 +1,4 @@
|
||||
extern crate clap;
|
||||
extern crate crossbeam_channel;
|
||||
#[macro_use]
|
||||
extern crate cursive;
|
||||
@@ -21,14 +22,15 @@ extern crate toml;
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate chrono;
|
||||
extern crate fern;
|
||||
|
||||
use std::process;
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
|
||||
use clap::{Arg, App};
|
||||
use cursive::traits::Identifiable;
|
||||
use cursive::view::ScrollStrategy;
|
||||
use cursive::views::*;
|
||||
use cursive::Cursive;
|
||||
|
||||
mod commands;
|
||||
@@ -50,8 +52,45 @@ use events::{Event, EventManager};
|
||||
use playlists::Playlists;
|
||||
use spotify::PlayerEvent;
|
||||
|
||||
fn setup_logging(filename: &str) -> Result<(), fern::InitError> {
|
||||
fern::Dispatch::new()
|
||||
// Perform allocation-free log formatting
|
||||
.format(|out, message, record| {
|
||||
out.finish(format_args!(
|
||||
"{} [{}] [{}] {}",
|
||||
chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
|
||||
record.target(),
|
||||
record.level(),
|
||||
message
|
||||
))
|
||||
})
|
||||
// Add blanket level filter -
|
||||
.level(log::LevelFilter::Trace)
|
||||
// - and per-module overrides
|
||||
.level_for("librespot", log::LevelFilter::Debug)
|
||||
// Output to stdout, files, and other Dispatch configurations
|
||||
.chain(fern::log_file(filename)?)
|
||||
// Apply globally
|
||||
.apply()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
cursive::logger::init();
|
||||
let matches = App::new("ncspot")
|
||||
.version("0.1.0")
|
||||
.author("Henrik Friedrichsen <henrik@affekt.org>")
|
||||
.about("cross-platform ncurses Spotify client")
|
||||
.arg(Arg::with_name("debug")
|
||||
.short("d")
|
||||
.long("debug")
|
||||
.value_name("FILE")
|
||||
.help("Enable debug logging to the specified file")
|
||||
.takes_value(true))
|
||||
.get_matches();
|
||||
|
||||
if let Some(filename) = matches.value_of("debug") {
|
||||
setup_logging(filename).expect("can't setup logging");
|
||||
}
|
||||
|
||||
// Things here may cause the process to abort; we must do them before creating curses windows
|
||||
// otherwise the error message will not be seen by a user
|
||||
@@ -74,8 +113,6 @@ fn main() {
|
||||
|
||||
let theme = theme::load(&cfg);
|
||||
|
||||
let logview = DebugView::new();
|
||||
|
||||
let mut cursive = Cursive::default();
|
||||
cursive.set_theme(theme.clone());
|
||||
|
||||
@@ -115,13 +152,10 @@ fn main() {
|
||||
|
||||
let queueview = ui::queue::QueueView::new(queue.clone());
|
||||
|
||||
let logview_scroller = ScrollView::new(logview).scroll_strategy(ScrollStrategy::StickToBottom);
|
||||
|
||||
let status = ui::statusbar::StatusBar::new(queue.clone(), spotify.clone());
|
||||
|
||||
let mut layout = ui::layout::Layout::new(status, &event_manager, theme)
|
||||
.view("search", search.with_id("search"), "Search")
|
||||
.view("log", logview_scroller, "Debug Log")
|
||||
.view("playlists", playlistsview, "Playlists")
|
||||
.view("queue", queueview, "Queue");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user