diff options
-rw-r--r-- | spotify-notify.vala | 116 |
1 files changed, 75 insertions, 41 deletions
diff --git a/spotify-notify.vala b/spotify-notify.vala index 683bae9..3f96f20 100644 --- a/spotify-notify.vala +++ b/spotify-notify.vala @@ -1,37 +1,56 @@ +/* spotify-notify.vala + * + * Media keys and song-change notification for the + * official Spotify client for Linux. + * + * Copyright 2011 Daniel Silverstone <dsilvers@digital-scurf.org> + */ + + [DBus (name = "org.mpris.MediaPlayer2.Player")] interface Player : Object { public abstract void play_pause () throws IOError; public abstract void next () throws IOError; public abstract void previous () throws IOError; public abstract void stop () throws IOError; - + } [DBus (name = "org.freedesktop.DBus.Properties")] interface PlayerProperties : Object { - public signal void properties_changed (string iface, HashTable<string, Variant> props, string[] invalidateds); - public abstract void get (string iface, string prop, out Variant value) throws IOError; + public signal void properties_changed (string iface, + HashTable<string, Variant> props, + string[] invalidateds); + public abstract void get (string iface, string prop, + out Variant value) throws IOError; } [DBus (name = "org.gnome.SettingsDaemon.MediaKeys")] interface MediaKeys : Object { - public abstract void grab_media_player_keys(string appname, uint32 n) throws IOError; - public signal void media_player_key_pressed (string appname, string key); + public abstract void grab_media_player_keys(string appname, + uint32 n) throws IOError; + public signal void media_player_key_pressed (string appname, + string key); } [DBus (name = "org.freedesktop.DBus")] interface BusInterface : Object { - public signal void name_owner_changed (string name, string old_owner, string new_owner); - public abstract void name_has_owner (string name, out bool has_owner) throws IOError; + public signal void name_owner_changed (string name, string old_owner, + string new_owner); + public abstract void name_has_owner (string name, out bool has_owner) + throws IOError; } [DBus (name = "org.freedesktop.Notifications")] interface Notify : Object { - public abstract uint32 notify (string app_name, uint32 replaces_id, string icon, string summary, string body, - string[] actions, HashTable<string, Variant> hints, int32 timeout) throws IOError; + public abstract uint32 notify (string app_name, uint32 replaces_id, + string icon, string summary, string body, + string[] actions, + HashTable<string, Variant> hints, + int32 timeout) throws IOError; public abstract void close_notification (uint32 id) throws IOError; public signal void notification_closed (uint32 id, uint32 reason); - + } Player player = null; @@ -66,7 +85,8 @@ class cbdobj { public void fetch_image_cb(Soup.Session sess, Soup.Message mess) { stdout.printf("Response for %s => %s\n", uri, targetfile); - stdout.printf("Status code %u, Content length: %zd\n", mess.status_code, (ssize_t)mess.response_body.length); + stdout.printf("Status code %u, Content length: %zd\n", + mess.status_code, (ssize_t)mess.response_body.length); if (mess.response_body.length > 0) { stdout.printf("Attempting to write to %s\n", targetfile); FileStream? f = FileStream.open(targetfile, "wb"); @@ -82,7 +102,8 @@ class cbdobj { } } -void fetch_image(string targetfile, string uri, Variant metadata, bool unsolicited) { +void fetch_image(string targetfile, string uri, + Variant metadata, bool unsolicited) { var msg = new Soup.Message ("GET", uri); stdout.printf("Prepping async fetch of %s\n", uri); cbdobj *cbd = new cbdobj (); @@ -103,22 +124,23 @@ void on_notification_closed (uint32 id, uint32 reason) { void metadata_changed(Variant metadata, bool unsolicited) { Variant? v_artist_a = metadata.lookup_value("xesam:artist", null); - Variant? v_artist = v_artist_a == null ? null : v_artist_a.get_child_value(0); + Variant? v_artist = (v_artist_a == null ? null : + v_artist_a.get_child_value(0)); Variant? v_album = metadata.lookup_value("xesam:album", null); Variant? v_title = metadata.lookup_value("xesam:title", null); Variant? v_arturl = metadata.lookup_value("mpris:artUrl", null); string? arturl = v_arturl == null ? null : v_arturl.get_string(); - + if (v_artist == null || v_album == null || v_title == null) { stderr.printf("Incomplete metadata!\n"); return; } - + string imgpath = ""; string? art_id; - + bool need_load_artwork = false; if (v_arturl != null) { /* Do we have the image cached? */ @@ -133,21 +155,22 @@ void metadata_changed(Variant metadata, bool unsolicited) { stderr.printf("Artwork %s found\n", imgpath); } } - + string artist = v_artist.get_string(); string album = v_album.get_string(); string title = v_title.get_string(); - + string msg = @"$title\n$album"; - + string[] actions = null; - HashTable<string, Variant> hints = new HashTable<string, Variant> (null, null); - + HashTable<string, Variant> hints = ( + new HashTable<string, Variant> (null, null)); + try { stdout.printf("Attempting to notify\n"); var nid = notify.notify("Spotify Interface", notification_id, - imgpath, + imgpath, artist, msg, actions, hints, @@ -163,7 +186,8 @@ void metadata_changed(Variant metadata, bool unsolicited) { } } -void on_properties_changed (string iface, HashTable<string, Variant> props, string[] invalidateds) { +void on_properties_changed (string iface, HashTable<string, Variant> props, + string[] invalidateds) { if (iface == "org.mpris.MediaPlayer2.Player") { Variant? mode = props.lookup("PlaybackStatus"); if (mode != null) { @@ -174,10 +198,12 @@ void on_properties_changed (string iface, HashTable<string, Variant> props, stri /* Switched to playing */ try { Variant v; - playerprops.get ("org.mpris.MediaPlayer2.Player", "Metadata", out v); + playerprops.get ("org.mpris.MediaPlayer2.Player", + "Metadata", out v); metadata_changed(v, false); } catch (IOError e) { - stderr.printf("Playback metadata retrieval failed: %s\n", e.message); + stderr.printf("Playback metadata retrieval failed: %s\n", + e.message); } } } @@ -191,8 +217,12 @@ void on_properties_changed (string iface, HashTable<string, Variant> props, stri void reconnect_spotify () { stdout.printf("Attempting to (re)connect to spotify\n"); try { - player = Bus.get_proxy_sync(BusType.SESSION, "com.spotify.qt", "/org/mpris/MediaPlayer2"); - playerprops = Bus.get_proxy_sync(BusType.SESSION, "com.spotify.qt", "/org/mpris/MediaPlayer2"); + player = Bus.get_proxy_sync(BusType.SESSION, + "com.spotify.qt", + "/org/mpris/MediaPlayer2"); + playerprops = Bus.get_proxy_sync(BusType.SESSION, + "com.spotify.qt", + "/org/mpris/MediaPlayer2"); playerprops.properties_changed.connect (on_properties_changed); stdout.printf("Success!\n"); } catch (IOError e) { @@ -201,7 +231,6 @@ void reconnect_spotify () { } void on_name_owner_changed (string name, string old_owner, string new_owner) { - // stdout.printf("name owner changed. name=%s old_owner=%s new_owner=%s\n", name, old_owner, new_owner); if (name == "com.spotify.qt") { if (new_owner == "") { /* Spotify went away */ @@ -217,11 +246,11 @@ void on_name_owner_changed (string name, string old_owner, string new_owner) { void on_media_player_key_pressed (string appname, string key) { stdout.printf("App %s key pressed: %s\n", appname, key); - + if (player == null) { stdout.printf("Key ignored, no spotify running\n"); } - + try { switch (key) { case "Play": @@ -251,39 +280,44 @@ void on_media_player_key_pressed (string appname, string key) { int main() { MediaKeys mkeys; BusInterface bi; - + imgcache = IMGCACHE_PATTERN.printf(Environment.get_variable("HOME")); DirUtils.create_with_parents(imgcache, 0700); - + try { soupsession = new Soup.SessionAsync (); stdout.printf("Getting media keys\n"); - mkeys = Bus.get_proxy_sync (BusType.SESSION, "org.gnome.SettingsDaemon", "/org/gnome/SettingsDaemon/MediaKeys"); + mkeys = Bus.get_proxy_sync (BusType.SESSION, + "org.gnome.SettingsDaemon", + "/org/gnome/SettingsDaemon/MediaKeys"); mkeys.media_player_key_pressed.connect (on_media_player_key_pressed); mkeys.grab_media_player_keys("Spotify", 0); stdout.printf("Getting notifications\n"); - notify = Bus.get_proxy_sync (BusType.SESSION, "org.freedesktop.Notifications", "/org/freedesktop/Notifications"); + notify = Bus.get_proxy_sync (BusType.SESSION, + "org.freedesktop.Notifications", + "/org/freedesktop/Notifications"); notify.notification_closed.connect (on_notification_closed); stdout.printf("Getting owner handles\n"); - bi = Bus.get_proxy_sync (BusType.SESSION, "org.freedesktop.DBus", "/org/freedesktop/DBus"); + bi = Bus.get_proxy_sync (BusType.SESSION, + "org.freedesktop.DBus", + "/org/freedesktop/DBus"); bi.name_owner_changed.connect (on_name_owner_changed); - + bool t; bi.name_has_owner("com.spotify.qt", out t); - + if (t) reconnect_spotify(); else stdout.printf("Spotify not running, will wait for notify\n"); - + } catch (IOError e) { stderr.printf ("%s\n", e.message); return 1; } - + loop = new MainLoop (); loop.run (); - + return 0; } -
\ No newline at end of file |