10 Commits
0.1.5 ... 0.2.0

Author SHA1 Message Date
Alexandr Bogomyakov
5d23b7da2d Bump version 2019-12-24 13:17:20 +03:00
Alexandr Bogomyakov
5cf2ab0e40 Add time feature with custom format. 2019-12-24 13:16:23 +03:00
AB
7c7d9070a4 Update separator. 2019-12-19 01:39:22 +03:00
AB
456d423f47 Improve player metadata displaying. 2019-12-19 01:36:57 +03:00
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
4 changed files with 150 additions and 57 deletions

View File

@@ -8,10 +8,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- 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
run: cargo build --verbose --release
env:

View File

@@ -1,9 +1,10 @@
[package]
name = "tmux-helper"
version = "0.1.0"
version = "0.2.0"
authors = ["Ultra Desu <ultradesu@hexor.ru>"]
edition = "2018"
[dependencies]
sys-info = "*"
dbus = "*"
chrono = "*"

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

@@ -1,5 +1,8 @@
extern crate chrono;
extern crate dbus;
use crate::dbus::blocking::stdintf::org_freedesktop_dbus::Properties;
use chrono::{DateTime, FixedOffset, Local, Utc};
use dbus::{arg, blocking::Connection};
use std::{env, fs, time::Duration};
use sys_info;
@@ -12,6 +15,7 @@ const TRACK_NAME: &str = "#[fg=colour3]";
const TRACK_ARTIST: &str = "#[fg=colour3]";
const TRACK_TIME: &str = "#[bg=colour252 fg=colour235 bold]";
#[derive(Debug, Clone)]
struct TrackInfo {
title: String,
artist: String,
@@ -69,17 +73,23 @@ fn cpu_load_bar(bar_len: i32) {
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 mut service: String = "org.mpris.MediaPlayer2.".to_owned();
service.push_str(player);
let proxy = conn.with_proxy(
service,
"/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();
let proxy = conn.with_proxy("org.freedesktop.DBus", "/", Duration::from_millis(5000));
let (names,): (Vec<String>,) = proxy.method_call("org.freedesktop.DBus", "ListNames", ())?;
let mut players: Vec<String> = Vec::new();
for name in names {
if name.contains("org.mpris.MediaPlayer2") {
players.push(name);
}
}
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(),
@@ -87,6 +97,15 @@ fn player_info(player: &str) -> Result<TrackInfo, Box<dyn std::error::Error>> {
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() {
@@ -108,7 +127,8 @@ fn player_info(player: &str) -> Result<TrackInfo, Box<dyn std::error::Error>> {
}
}
}
let position: Box<dyn arg::RefArg> = proxy.get("org.mpris.MediaPlayer2.Player", "Position")?;
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> =
@@ -119,7 +139,14 @@ fn player_info(player: &str) -> Result<TrackInfo, Box<dyn std::error::Error>> {
"Paused" => track_info.status = "".to_string(),
_ => track_info.status = "".to_string(),
};
Ok(track_info)
players_vec.push(track_info);
}
for player in &players_vec {
if player.status == "".to_string() {
return Ok(player.clone());
}
}
Ok(players_vec[players_vec.len() - 1].clone())
}
fn format_time(sec: i64) -> String {
@@ -129,9 +156,24 @@ fn format_time(sec: i64) -> String {
result.to_string()
}
fn get_time(utc: bool, mut format: &str) {
// Format reference: https://docs.rs/chrono/0.4.10/chrono/format/strftime/index.html
if format.len() == 0 {
format = "%H:%M";
}
if utc {
let local_time = Local::now();
let utc_time = DateTime::<Utc>::from_utc(local_time.naive_utc(), Utc);
println!("{}", utc_time.format(format));
} else {
let local_time = Local::now();
println!("{}", local_time.format(format));
}
}
fn main() {
let args: Vec<String> = env::args().collect();
let help_text: &str = "Available commands -mb, -cb";
let help_text: &str = "Available commands -mb, -cb, -tl <TIME FORMAT>, -tu <TIME FORMAT>, -p";
match args.len() {
1 => {
panic!(help_text);
@@ -139,23 +181,56 @@ fn main() {
2 => match args[1].as_ref() {
"-cb" => cpu_load_bar(15),
"-mb" => mem_load_bar(15),
"-p" => match player_info("cmus") {
"-tl" => get_time(false, ""),
"-tu" => get_time(true, ""),
"-p" => match player_info(get_player().unwrap()) {
Ok(mut track_info) => {
let title_len = 30;
let artist_len = 30;
if track_info.title.len() >= title_len {
track_info.title.truncate(title_len);
track_info.title.push_str("..");
let mut title_len = 30;
let mut artist_len = 30;
let mut separator: String = "".to_string();
let max_shift = 6;
if track_info.artist.chars().count() == 0 {
separator = "".to_string();
title_len += artist_len;
}
if track_info.artist.len() >= artist_len {
track_info.artist.truncate(artist_len);
track_info.artist.push_str("..");
if artist_len + max_shift >= track_info.artist.chars().count() {
artist_len = track_info.artist.chars().count()
}
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 {
artist.push_str("..");
break;
}
artist.push(ch);
counter += 1;
}
track_info.artist = artist;
}
if title_len + max_shift >= track_info.title.chars().count() {
title_len = track_info.title.chars().count()
}
if track_info.title.len() > title_len {
let mut title: String = String::new();
let mut counter = 0;
for ch in track_info.title.chars() {
if counter == title_len {
title.push_str("..");
break;
}
title.push(ch);
counter += 1;
}
track_info.title = title;
}
println!(
"#[none]#[bold]{}{}{}#[none]{} - {}{} {}[{}/{}] {} {}",
"#[none]#[bold]{}{}{}#[none]{}{}{}{} {}[{}/{}] {} {}",
TRACK_NAME,
track_info.title,
END,
separator,
TRACK_ARTIST,
track_info.artist,
END,
@@ -170,6 +245,11 @@ fn main() {
},
_ => panic!(help_text),
},
3 => match args[1].as_ref() {
"-tl" => get_time(false, args[2].as_ref()),
"-tu" => get_time(true, args[2].as_ref()),
_ => panic!(help_text),
},
_ => {
panic!(help_text);
}