Explorar o código

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 %!s(int64=7) %!d(string=hai) anos
pai
achega
66f08fdecd
Modificáronse 2 ficheiros con 31 adicións e 22 borrados
  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();
     }
 }