6 Commits
0.1.5 ... 0.1.8

Author SHA1 Message Date
Ultra Desu
cd854d450a Fix files. 2019-12-19 00:03:15 +03:00
Ultra Desu
7a934a063f Fix player metadata shorting. 2019-12-19 00:02:33 +03:00
Alexandr Bogomyakov
08cf01ee81 Add multiplayer support. 2019-12-17 15:10:31 +03:00
Alexandr Bogomyakov
530a753527 Add multiplayer support. 2019-12-17 15:05:24 +03:00
House of Vanity
614185e7f8 Create LICENSE-WTFPL
Add license
2019-12-10 13:38:34 +03:00
Alexandr Bogomyakov
ddd09761f5 Fix workflow. 2019-12-04 15:24:04 +03:00
3 changed files with 119 additions and 55 deletions

View File

@@ -8,10 +8,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
- name: Pre-build - name: Pre-build
run: apt install -y libdbus-1-dev pkg-config libdbus-1-3 run: sudo apt install -y libdbus-1-dev pkg-config libdbus-1-3
- name: Build - name: Build
run: cargo build --verbose --release run: cargo build --verbose --release
env: env:

13
LICENSE-WTFPL Normal file
View File

@@ -0,0 +1,13 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

View File

@@ -12,6 +12,7 @@ const TRACK_NAME: &str = "#[fg=colour3]";
const TRACK_ARTIST: &str = "#[fg=colour3]"; const TRACK_ARTIST: &str = "#[fg=colour3]";
const TRACK_TIME: &str = "#[bg=colour252 fg=colour235 bold]"; const TRACK_TIME: &str = "#[bg=colour252 fg=colour235 bold]";
#[derive(Debug, Clone)]
struct TrackInfo { struct TrackInfo {
title: String, title: String,
artist: String, artist: String,
@@ -69,57 +70,80 @@ fn cpu_load_bar(bar_len: i32) {
print!("{:.2} LA1", one); print!("{:.2} LA1", one);
} }
fn player_info(player: &str) -> Result<TrackInfo, Box<dyn std::error::Error>> { fn get_player() -> Result<Vec<String>, Box<dyn std::error::Error>> {
let conn = Connection::new_session()?; let conn = Connection::new_session()?;
let mut service: String = "org.mpris.MediaPlayer2.".to_owned(); let proxy = conn.with_proxy("org.freedesktop.DBus", "/", Duration::from_millis(5000));
service.push_str(player); let (names,): (Vec<String>,) = proxy.method_call("org.freedesktop.DBus", "ListNames", ())?;
let proxy = conn.with_proxy( let mut players: Vec<String> = Vec::new();
service, for name in names {
"/org/mpris/MediaPlayer2", if name.contains("org.mpris.MediaPlayer2") {
Duration::from_millis(5000), players.push(name);
);
let metadata: Box<dyn arg::RefArg> = proxy.get("org.mpris.MediaPlayer2.Player", "Metadata")?;
let mut iter = metadata.as_iter().unwrap();
let mut track_info = TrackInfo {
artist: "".to_string(),
title: "".to_string(),
position: "".to_string(),
duration: "".to_string(),
status: "".to_string(),
};
while let Some(key) = iter.next() {
if key.as_str() == Some("xesam:title") {
if let Some(title) = iter.next().unwrap().as_str() {
track_info.title = title.to_string();
}
} }
if key.as_str() == Some("mpris:length") { }
if let Some(length) = iter.next().unwrap().as_i64() {
track_info.duration = format_time(length / 1000000); Ok(players)
}
fn player_info(players: Vec<String>) -> Result<TrackInfo, Box<dyn std::error::Error>> {
let mut players_vec: Vec<TrackInfo> = Vec::new();
for player in players {
let mut track_info = TrackInfo {
artist: "".to_string(),
title: "".to_string(),
position: "".to_string(),
duration: "".to_string(),
status: "".to_string(),
};
let conn = Connection::new_session()?;
let proxy = conn.with_proxy(
player,
"/org/mpris/MediaPlayer2",
Duration::from_millis(5000),
);
let metadata: Box<dyn arg::RefArg> =
proxy.get("org.mpris.MediaPlayer2.Player", "Metadata")?;
let mut iter = metadata.as_iter().unwrap();
while let Some(key) = iter.next() {
if key.as_str() == Some("xesam:title") {
if let Some(title) = iter.next().unwrap().as_str() {
track_info.title = title.to_string();
}
} }
} if key.as_str() == Some("mpris:length") {
if key.as_str() == Some("xesam:artist") { if let Some(length) = iter.next().unwrap().as_i64() {
if let Some(mut artists) = iter.next().unwrap().as_iter() { track_info.duration = format_time(length / 1000000);
while let Some(artist) = artists.next() { }
if let Some(mut line) = artist.as_iter() { }
track_info.artist = line.next().unwrap().as_str().unwrap().to_string(); if key.as_str() == Some("xesam:artist") {
if let Some(mut artists) = iter.next().unwrap().as_iter() {
while let Some(artist) = artists.next() {
if let Some(mut line) = artist.as_iter() {
track_info.artist = line.next().unwrap().as_str().unwrap().to_string();
}
} }
} }
} }
} }
let position: Box<dyn arg::RefArg> =
proxy.get("org.mpris.MediaPlayer2.Player", "Position")?;
track_info.position = format_time(position.as_i64().unwrap() / 1000000);
// ugly
let _status_text_box: Box<dyn arg::RefArg> =
proxy.get("org.mpris.MediaPlayer2.Player", "PlaybackStatus")?;
let _status_text = _status_text_box.as_str().unwrap();
match _status_text.as_ref() {
"Playing" => track_info.status = "".to_string(),
"Paused" => track_info.status = "".to_string(),
_ => track_info.status = "".to_string(),
};
players_vec.push(track_info);
} }
let position: Box<dyn arg::RefArg> = proxy.get("org.mpris.MediaPlayer2.Player", "Position")?; for player in &players_vec {
track_info.position = format_time(position.as_i64().unwrap() / 1000000); if player.status == "".to_string() {
// ugly return Ok(player.clone());
let _status_text_box: Box<dyn arg::RefArg> = }
proxy.get("org.mpris.MediaPlayer2.Player", "PlaybackStatus")?; }
let _status_text = _status_text_box.as_str().unwrap(); Ok(players_vec[players_vec.len() - 1].clone())
match _status_text.as_ref() {
"Playing" => track_info.status = "".to_string(),
"Paused" => track_info.status = "".to_string(),
_ => track_info.status = "".to_string(),
};
Ok(track_info)
} }
fn format_time(sec: i64) -> String { fn format_time(sec: i64) -> String {
@@ -139,23 +163,51 @@ fn main() {
2 => match args[1].as_ref() { 2 => match args[1].as_ref() {
"-cb" => cpu_load_bar(15), "-cb" => cpu_load_bar(15),
"-mb" => mem_load_bar(15), "-mb" => mem_load_bar(15),
"-p" => match player_info("cmus") { "-p" => match player_info(get_player().unwrap()) {
Ok(mut track_info) => { Ok(mut track_info) => {
let title_len = 30; let mut title_len = 30;
let artist_len = 30; let mut artist_len = 30;
if track_info.title.len() >= title_len { let mut separator: String = " - ".to_string();
track_info.title.truncate(title_len); let max_shift = 6;
track_info.title.push_str(".."); if title_len + max_shift >= track_info.title.chars().count() {
title_len = track_info.title.chars().count()
} }
if track_info.artist.len() >= artist_len { if track_info.title.len() > title_len {
track_info.artist.truncate(artist_len); let mut title: String = String::new();
track_info.artist.push_str(".."); let mut counter = 0;
for ch in track_info.title.chars() {
if counter == title_len {
break;
}
title.push(ch);
counter += 1;
}
title.push_str("..");
track_info.title = title;
}
if artist_len + max_shift >= track_info.artist.chars().count() {
artist_len = track_info.artist.chars().count()
}
if track_info.artist.chars().count() == 0 {separator = "".to_string()}
if track_info.artist.len() > artist_len {
let mut artist: String = String::new();
let mut counter = 0;
for ch in track_info.artist.chars() {
if counter == artist_len {
break;
}
artist.push(ch);
counter += 1;
}
artist.push_str("..");
track_info.artist = artist;
} }
println!( println!(
"#[none]#[bold]{}{}{}#[none]{} - {}{} {}[{}/{}] {} {}", "#[none]#[bold]{}{}{}#[none]{}{}{}{} {}[{}/{}] {} {}",
TRACK_NAME, TRACK_NAME,
track_info.title, track_info.title,
END, END,
separator,
TRACK_ARTIST, TRACK_ARTIST,
track_info.artist, track_info.artist,
END, END,