소스 검색

Better titles and bugfixes for mpd

We handle the case where no song is playing (reached end of the
playlist), as well as handle songs without actual tags.
Thomas Dy 7 년 전
부모
커밋
66f08fdecd
2개의 변경된 파일31개의 추가작업 그리고 22개의 파일을 삭제
  1. 1 1
      src/widgets/mod.rs
  2. 30 21
      src/widgets/music.rs

+ 1 - 1
src/widgets/mod.rs

@@ -17,7 +17,7 @@ pub enum Message {
     Quit,
     MousePress(u16),
     BspwmEvent(String),
-    MpdEvent(mpd::status::State, String, String),
+    MpdEvent(mpd::status::State, Option<mpd::song::Song>),
     XcbEvent(xcb::GenericEvent)
 }
 

+ 30 - 21
src/widgets/music.rs

@@ -1,7 +1,9 @@
 use mpd;
+use mpd::song::Song;
 use mpd::status::State;
 use mpd::idle;
 use mpd::idle::Idle;
+use std::path::Path;
 use std::thread;
 use ui::draw_context::DrawContext;
 use widgets::{Message, MessageSender, Widget};
@@ -13,8 +15,7 @@ pub struct Music {
     context: DrawContext,
     tx: MessageSender,
     state: State,
-    artist: String,
-    title: String,
+    song: Option<Song>,
     last_pos: u16
 }
 
@@ -23,8 +24,7 @@ pub fn mpd(tx: MessageSender, context: DrawContext) -> Music {
         context: context,
         tx: tx,
         state: State::Stop,
-        artist: "".to_string(),
-        title: "".to_string(),
+        song: None,
         last_pos: 0
     }
 }
@@ -38,6 +38,21 @@ impl Music {
         }
     }
 
+    fn get_text(&self) -> String {
+        match self.song {
+            Some(ref song) => match (&song.title, &song.tags.get("Artist")) {
+                (&Some(ref title), &Some(ref artist)) => format!("{} - {}", title, artist),
+                (&Some(ref title), &None) => title.to_string(),
+                _ => {
+                    let path = Path::new(&song.file);
+                    let path = path.file_name().and_then(|s| s.to_str());
+                    path.unwrap_or("Unknown").to_string()
+                }
+            },
+            None => "mpd".to_string()
+        }
+    }
+
     fn redraw(&mut self) {
         let x = self.last_pos;
         self.context.set_bg_color(0x0, 0x0, 0x0, 0xFFFF);
@@ -62,13 +77,7 @@ impl Widget for Music {
         self.context.draw_bg(x, icon_width + MARGIN * 2);
         self.context.draw_text(self.icon(), x + MARGIN);
 
-
-        let text = if self.state == State::Stop {
-            "Stopped".to_string()
-        }
-        else {
-            format!("{} - {}", self.artist, self.title)
-        };
+        let text = self.get_text();
         let text_width = WIDTH - MARGIN * 4 - icon_width;
         self.context.set_bg_color(0x0, 0x0, 0x0, 0xFFFF);
         self.context.draw_bg(x + icon_width + MARGIN * 3, text_width);
@@ -81,10 +90,9 @@ impl Widget for Music {
 
     fn handle_event(&mut self, event: &Message) -> bool {
         match event {
-            &Message::MpdEvent(ref state, ref artist, ref title) => {
+            &Message::MpdEvent(ref state, ref song) => {
                 self.state = state.clone();
-                self.artist = artist.clone();
-                self.title = title.clone();
+                self.song = song.clone();
                 self.redraw();
             },
             &Message::MousePress(_x) => {
@@ -99,13 +107,14 @@ impl Widget for Music {
 fn monitor_thread(tx: MessageSender) {
     let mut conn = mpd::client::Client::connect("127.0.0.1:6600").unwrap();
     loop {
-        let unknown = "Unknown".to_string();
-        let state = conn.status().unwrap().state;
-        let song = conn.currentsong().unwrap().unwrap();
-        let artist = song.tags.get("Artist").unwrap_or(&unknown);
-        let title = song.title.as_ref().unwrap_or(&unknown);
-
-        tx.send(Message::MpdEvent(state, artist.clone(), title.clone())).expect("Failed to send mpd event");
+        match (conn.status(), conn.currentsong()) {
+            (Ok(status), Ok(song)) => {
+                let state = status.state;
+                let event = Message::MpdEvent(state, song);
+                tx.send(event).expect("Failed to send mpd event");
+            },
+            _ => {}
+        }
         conn.wait(&[idle::Subsystem::Player]).ok();
     }
 }