banshee r3356 - in trunk/banshee: . src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Audioscrobbler src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio src/Libraries/Lastfm/Lastfm src/Libraries/Mono.Media/Media.Playlists.Xspf



Author: ahixon
Date: Fri Feb 29 06:09:27 2008
New Revision: 3356
URL: http://svn.gnome.org/viewvc/banshee?rev=3356&view=rev

Log:
2008-02-29  Alexander Hixon  <hixon alexander mediati org>

	* src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/StationSource.cs:
	* src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/LastfmTrackInfo.cs:
	Modify the LastfmTrackInfo object, and add in the new trackauth variable
	in the constructor and associated property. We get the trackauth value
	from the track returned from Last.fm (lastfm:trackauth).

	* src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Audioscrobbler/AudioscrobblerService.cs:
	Only submit NowPlaying tracks if the track is more than 30 seconds in length
	and the user has enabled scrobbling of tracks.

	* src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Audioscrobbler/Queue.cs:
	Support the new TrackAuth property in LastfmTrackInfo, submit that and the
	correct source code if the track was from radio, otherwise say it was from
	the library.

	* src/Libraries/Lastfm/Lastfm/AudioscrobblerConnection.cs: Lots of cleanups
	to do with HACKING guidelines, trying to send stuff when we're not allowed
	to (ie not connected), and *heaps* of logic/name cleanups. 


Modified:
   trunk/banshee/ChangeLog
   trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Audioscrobbler/AudioscrobblerService.cs
   trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Audioscrobbler/Queue.cs
   trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/LastfmTrackInfo.cs
   trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/StationSource.cs
   trunk/banshee/src/Libraries/Lastfm/Lastfm/AudioscrobblerConnection.cs
   trunk/banshee/src/Libraries/Mono.Media/Media.Playlists.Xspf/Track.cs

Modified: trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Audioscrobbler/AudioscrobblerService.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Audioscrobbler/AudioscrobblerService.cs	(original)
+++ trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Audioscrobbler/AudioscrobblerService.cs	Fri Feb 29 06:09:27 2008
@@ -209,8 +209,7 @@
                 track.ArtistName != "" && track.TrackTitle != "" &&
                 (st.PlayTime >  track.Duration.TotalMilliseconds / 2 || st.PlayTime > 240 * 1000)) {
                     if (!connection.Started) {
-                        // Lazy-connect.
-                        connection.Connect ();
+                        connection.Start ();
                     }
                     
                     queue.Add (track, song_start_time);
@@ -231,7 +230,9 @@
                     queued = false;
 
                     // Queue as now playing
-                    if (last_track != null) {
+                    if (last_track != null && last_track.Duration.TotalSeconds > 30 &&
+                        (actions["AudioscrobblerEnableAction"] as ToggleAction).Active) {
+                        
                         connection.NowPlaying (last_track.ArtistName, last_track.TrackTitle,
                             last_track.AlbumTitle, last_track.Duration.TotalSeconds, last_track.TrackNumber);
                     }

Modified: trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Audioscrobbler/Queue.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Audioscrobbler/Queue.cs	(original)
+++ trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Audioscrobbler/Queue.cs	Fri Feb 29 06:09:27 2008
@@ -44,6 +44,7 @@
 using Banshee.Sources;
 
 using Lastfm;
+using Banshee.Lastfm.Radio;
 
 namespace Banshee.Lastfm.Audioscrobbler
 {
@@ -63,11 +64,16 @@
                 //this.musicbrainzid = track.MusicBrainzId;
                 
                 this.musicbrainzid = "";
+                
+                // set trackauth value, otherwise empty string is default
+                if (track is LastfmTrackInfo) {
+                    this.track_auth = (track as LastfmTrackInfo).TrackAuth;
+                }
             }
 
             public QueuedTrack (string artist, string album,
                                 string title, int track_number, int duration, long start_time,
-                                string musicbrainzid)
+                                string musicbrainzid, string track_auth)
             {
                 this.artist = artist;
                 this.album = album;
@@ -76,6 +82,7 @@
                 this.duration = duration;
                 this.start_time = start_time;
                 this.musicbrainzid = musicbrainzid;
+                this.track_auth = track_auth;
             }
 
             public long StartTime {
@@ -105,6 +112,10 @@
             public string MusicBrainzId {
                 get { return musicbrainzid; }
             }
+            
+            public string TrackAuth {
+                get { return track_auth; }
+            }
 
             string artist;
             string album;
@@ -113,12 +124,12 @@
             int duration;
             string musicbrainzid;
             long start_time;
+            string track_auth = String.Empty;
         }
 
         List<QueuedTrack> queue;
         string xml_path;
         bool dirty;
-        SourceManager sourcemanager;
 
         public event EventHandler TrackAdded;
 
@@ -132,8 +143,6 @@
             if (!Directory.Exists(xmlfilepath)) {
                 Directory.CreateDirectory (xmlfilepath);
             }
-            
-            sourcemanager = ServiceManager.Get<SourceManager> ("SourceManager");
 
             Load ();
         }
@@ -161,6 +170,7 @@
                 writer.WriteElementString ("Duration", track.Duration.ToString());
                 writer.WriteElementString ("StartTime", track.StartTime.ToString());
                 writer.WriteElementString ("MusicBrainzId", track.MusicBrainzId);
+                writer.WriteElementString ("TrackAuth", track.TrackAuth);
                 writer.WriteEndElement (); // Track
             }
             writer.WriteEndElement (); // AudioscrobblerQueue
@@ -186,6 +196,7 @@
                     int duration = 0;
                     long start_time = 0;
                     string musicbrainzid = "";
+                    string track_auth = "";
 
                     foreach (XmlNode child in node.ChildNodes) {
                         if (child.Name == "Artist" && child.ChildNodes.Count != 0) {
@@ -202,11 +213,13 @@
                             start_time = Convert.ToInt64 (child.ChildNodes [0].Value);
                         } else if (child.Name == "MusicBrainzId" && child.ChildNodes.Count != 0) {
                             musicbrainzid = child.ChildNodes [0].Value;
+                        } else if (child.Name == "TrackAuth" && child.ChildNodes.Count != 0) {
+                            track_auth = child.ChildNodes [0].Value;
                         }
                     }
 
                     queue.Add (new QueuedTrack (artist, album, title, track_number, duration,
-                        start_time, musicbrainzid));
+                        start_time, musicbrainzid, track_auth));
                 }
             } catch { 
             }
@@ -214,7 +227,6 @@
 
         public string GetTransmitInfo (out int numtracks)
         {
-            string str_track_number = "";
             StringBuilder sb = new StringBuilder ();
 
             int i;
@@ -224,15 +236,22 @@
 
                 QueuedTrack track = (QueuedTrack) queue[i];
                 
+                string str_track_number = String.Empty;
                 if (track.TrackNumber != 0)
                     str_track_number = track.TrackNumber.ToString();
+                 
+                string source = "P"; /* chosen by user */   
+                if (track.TrackAuth.Length != 0) {
+                    // from last.fm 
+                    source = "L" + track.TrackAuth;
+                }
 
                 sb.AppendFormat (
                     "&a[{9}]={0}&t[{9}]={1}&i[{9}]={2}&o[{9}]={3}&r[{9}]={4}&l[{9}]={5}&b[{9}]={6}&n[{9}]={7}&m[{9}]={8}",
                     HttpUtility.UrlEncode (track.Artist),
                     HttpUtility.UrlEncode (track.Title),
                     track.StartTime.ToString (),
-                    "P" /* source: chosen by user */, 
+                    source, 
                     ""  /* rating: L/B/S */, 
                     track.Duration.ToString (),
                     HttpUtility.UrlEncode (track.Album),

Modified: trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/LastfmTrackInfo.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/LastfmTrackInfo.cs	(original)
+++ trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/LastfmTrackInfo.cs	Fri Feb 29 06:09:27 2008
@@ -44,6 +44,7 @@
         private StationSource station;
         private Track track;
         private bool loved, hated;
+        private string trackauth;
 
         public LastfmTrackInfo ()
         {
@@ -62,10 +63,15 @@
         public bool Hated {
             get { return hated; }
         }
+        
+        public string TrackAuth {
+            get { return trackauth; }
+        }
 
-        public LastfmTrackInfo (Track track, StationSource station)
+        public LastfmTrackInfo (Track track, StationSource station, string trackauth)
         {
             this.station = station;
+            this.trackauth = trackauth;
             Uri = new SafeUri (track.Locations[0]);
             ArtistName = track.Creator;
             TrackTitle = track.Title;

Modified: trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/StationSource.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/StationSource.cs	(original)
+++ trunk/banshee/src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/StationSource.cs	Fri Feb 29 06:09:27 2008
@@ -340,7 +340,7 @@
                     } else {
                         List<TrackInfo> new_tracks = new List<TrackInfo> ();
                         foreach (Media.Playlists.Xspf.Track track in playlist.Tracks) {
-                            TrackInfo ti = new LastfmTrackInfo (track, this);
+                            TrackInfo ti = new LastfmTrackInfo (track, this, track.GetExtendedValue ("trackauth"));
                             new_tracks.Add (ti);
                             lock (track_model) {
                                 track_model.Add (ti);

Modified: trunk/banshee/src/Libraries/Lastfm/Lastfm/AudioscrobblerConnection.cs
==============================================================================
--- trunk/banshee/src/Libraries/Lastfm/Lastfm/AudioscrobblerConnection.cs	(original)
+++ trunk/banshee/src/Libraries/Lastfm/Lastfm/AudioscrobblerConnection.cs	Fri Feb 29 06:09:27 2008
@@ -37,18 +37,19 @@
 using System.Web;
 
 using Hyena;
+using Mono.Unix;
 
 namespace Lastfm
 {
     public class AudioscrobblerConnection
     {
         enum State {
-            IDLE,
-            NEED_HANDSHAKE,
-            NEED_TRANSMIT,
-            WAITING_FOR_REQ_STREAM,
-            WAITING_FOR_HANDSHAKE_RESP,
-            WAITING_FOR_RESP
+            Idle,
+            NeedHandshake,
+            NeedTransmit,
+            WaitingForRequestStream,
+            WaitingForHandshakeResp,
+            WaitingForResponse
         };
 
         const int TICK_INTERVAL = 2000; /* 2 seconds */
@@ -63,13 +64,14 @@
 
         string post_url;
         string session_id = null;
-        string now_playing_url = "%now_playing_uri%"; /* default placeholder url */
-        bool connected = false;
+        string now_playing_url;
+        
+        bool connected = false; /* if we're connected to network or not */
         public bool Connected {
             get { return connected; }
         }
         
-        bool started = false;
+        bool started = false; /* engine has started and was/is connected to AS */
         public bool Started {
             get { return started; }
         }
@@ -84,7 +86,7 @@
         int hard_failure_retry_sec = 60;
         
         HttpWebRequest now_playing_post;
-        string now_playing_uri;
+        string current_now_playing_uri;
         HttpWebRequest current_web_req;
         IAsyncResult current_async_result;
         State state;
@@ -93,7 +95,7 @@
         {
             LastfmCore.Account.Updated += AccountUpdated;
             
-            state = State.IDLE;
+            state = State.Idle;
             this.queue = queue;
         }
         
@@ -101,14 +103,7 @@
         {
             Stop ();
             session_id = null;
-            Connect ();
-        }
-        
-        public void Connect ()
-        {
-            if (!started) {
-                Start ();
-            }
+            Start ();
         }
         
         public void UpdateNetworkState (bool connected)
@@ -117,22 +112,26 @@
             this.connected = connected;
         }
 
-        private void Start ()
+        public void Start ()
         {            
+            if (started) {
+                return;
+            }
+            
             started = true;
+            hard_failures = 0;
             queue.TrackAdded += delegate(object o, EventArgs args) {
                 StartTransitionHandler ();
             };
             
             queue.Load ();
-            
             StartTransitionHandler ();
         }
 
         private void StartTransitionHandler ()
         {
             if (!started) {
-                // Don't run if we're not actually connected.
+                // Don't run if we're not actually started.
                 return;
             }
             
@@ -143,10 +142,8 @@
                 timer.Elapsed += new ElapsedEventHandler (StateTransitionHandler);
                 
                 timer.Start ();
-                //Console.WriteLine ("Timer started.");
             } else if (!timer.Enabled) {
                 timer.Start ();
-                //Console.WriteLine ("Restarting timer from stopped state.");
             }
         }
 
@@ -172,7 +169,7 @@
 
         private void StateTransitionHandler (object o, ElapsedEventArgs e)
         {
-            Hyena.Log.DebugFormat ("State transition handler running; state: {0}, connected {1}", state, connected);
+            Hyena.Log.DebugFormat ("State transition handler running; state: {0}, connected: {1}", state, connected);
             
             /* if we're not connected, don't bother doing anything
              * involving the network. */
@@ -180,24 +177,26 @@
                 return;
             }
                         
-            if ((state == State.IDLE || state == State.NEED_TRANSMIT) && hard_failures > 2) {
-                state = State.NEED_HANDSHAKE;
+            if ((state == State.Idle || state == State.NeedTransmit) && hard_failures > 2) {
+                state = State.NeedHandshake;
                 hard_failures = 0;
             }
+            
+            
 
             /* and address changes in our engine state */
             switch (state) {
-            case State.IDLE:
+            case State.Idle:
                 if (LastfmCore.Account.UserName != null &&
                     LastfmCore.Account.CryptedPassword != null && session_id == null) {
                     
-                    state = State.NEED_HANDSHAKE;
+                    state = State.NeedHandshake;
                 } else {
-                    if (queue.Count > 0) {
-                        state = State.NEED_TRANSMIT;
-                    } else if (now_playing_uri != null) {
+                    if (queue.Count > 0 && session_id != null) {
+                        state = State.NeedTransmit;
+                    } else if (current_now_playing_uri != null && session_id != null) {
                         // Now playing info needs to be sent
-                        NowPlaying (now_playing_uri);
+                        NowPlaying (current_now_playing_uri);
                     } else {
                         Hyena.Log.DebugFormat ("State transition handler going to sleep.");
                         StopTransitionHandler ();
@@ -205,20 +204,20 @@
                 }
                 
                 break;
-            case State.NEED_HANDSHAKE:
+            case State.NeedHandshake:
                 if (DateTime.Now > next_interval) {
                     Handshake ();
                 }
                 
                 break;
-            case State.NEED_TRANSMIT:
+            case State.NeedTransmit:
                 if (DateTime.Now > next_interval) {
                     TransmitQueue ();
                 }
                 break;
-            case State.WAITING_FOR_RESP:
-            case State.WAITING_FOR_REQ_STREAM:
-            case State.WAITING_FOR_HANDSHAKE_RESP:
+            case State.WaitingForResponse:
+            case State.WaitingForRequestStream:
+            case State.WaitingForHandshakeResp:
                 /* nothing here */
                 break;
             }
@@ -227,13 +226,13 @@
         //
         // Async code for transmitting the current queue of tracks
         //
-        class TransmitState
+        internal class TransmitState
         {
             public StringBuilder StringBuilder;
             public int Count;
         }
 
-        void TransmitQueue ()
+        private void TransmitQueue ()
         {
             int num_tracks_transmitted;
 
@@ -266,20 +265,20 @@
             ts.Count = num_tracks_transmitted;
             ts.StringBuilder = sb;
 
-            state = State.WAITING_FOR_REQ_STREAM;
+            state = State.WaitingForRequestStream;
             current_async_result = current_web_req.BeginGetRequestStream (TransmitGetRequestStream, ts);
             if (!(current_async_result.AsyncWaitHandle.WaitOne (TIME_OUT, false))) {
 		        Hyena.Log.Warning ("Audioscrobbler upload failed", 
                                              "The request timed out and was aborted", false);
                 next_interval = DateTime.Now + new TimeSpan (0, 0, RETRY_SECONDS);
                 hard_failures++;
-                state = State.IDLE;
+                state = State.Idle;
                 
                 current_web_req.Abort();
             }
         }
 
-        void TransmitGetRequestStream (IAsyncResult ar)
+        private void TransmitGetRequestStream (IAsyncResult ar)
         {
             Stream stream;
 
@@ -289,7 +288,7 @@
             catch (Exception e) {
                 Hyena.Log.Warning ("Failed to get the request stream", e.ToString (), false);
 
-                state = State.IDLE;
+                state = State.Idle;
                 next_interval = DateTime.Now + new TimeSpan (0, 0, RETRY_SECONDS);
                 return;
             }
@@ -301,16 +300,16 @@
             writer.Write (sb.ToString ());
             writer.Close ();
 
-            state = State.WAITING_FOR_RESP;
+            state = State.WaitingForResponse;
             current_async_result = current_web_req.BeginGetResponse (TransmitGetResponse, ts);
             if (current_async_result == null) {
                 next_interval = DateTime.Now + new TimeSpan (0, 0, RETRY_SECONDS);
                 hard_failures++;
-                state = State.IDLE;
+                state = State.Idle;
             }
         }
 
-        void TransmitGetResponse (IAsyncResult ar)
+        private void TransmitGetResponse (IAsyncResult ar)
         {
             WebResponse resp;
 
@@ -318,9 +317,9 @@
                 resp = current_web_req.EndGetResponse (ar);
             }
             catch (Exception e) {
-                Console.WriteLine ("Failed to get the response: {0}", e);
+                Hyena.Log.Warning (String.Format("Failed to get the response: {0}", e));
 
-                state = State.IDLE;
+                state = State.Idle;
                 next_interval = DateTime.Now + new TimeSpan (0, 0, RETRY_SECONDS);
                 return;
             }
@@ -340,39 +339,43 @@
                     Hyena.Log.Warning ("Audioscrobbler upload failed", line.Substring ("FAILED".Length).Trim(), false);
                     last_upload_failed_logged = now;
                 }
+                
                 /* retransmit the queue on the next interval */
                 hard_failures++;
-                state = State.NEED_TRANSMIT;
+                state = State.NeedTransmit;
             }
             else if (line.StartsWith ("BADSESSION")) {
                 if (now - last_upload_failed_logged > TimeSpan.FromMinutes(FAILURE_LOG_MINUTES)) {
                     Hyena.Log.Warning ("Audioscrobbler upload failed", "session ID sent was invalid", false);
                     last_upload_failed_logged = now;
                 }
+                
                 /* attempt to re-handshake (and retransmit) on the next interval */
                 session_id = null;
                 next_interval = DateTime.Now + new TimeSpan (0, 0, RETRY_SECONDS);
-                state = State.NEED_HANDSHAKE;
+                state = State.NeedHandshake;
                 return;
-            }
-            else if (line.StartsWith ("OK")) {
+            } else if (line.StartsWith ("OK")) {
                 /* if we've previously logged failures, be nice and log the successful upload. */
                 if (last_upload_failed_logged != DateTime.MinValue) {
                     Hyena.Log.Debug ("Audioscrobbler upload succeeded");
                     last_upload_failed_logged = DateTime.MinValue;
                 }
+                
+                hard_failures = 0;
+                
                 /* we succeeded, pop the elements off our queue */
                 queue.RemoveRange (0, ts.Count);
                 queue.Save ();
                 
-                state = State.IDLE;
-            }
-            else {
+                state = State.Idle;
+            } else {
                 if (now - last_upload_failed_logged > TimeSpan.FromMinutes(FAILURE_LOG_MINUTES)) {
                     Hyena.Log.Warning ("Audioscrobbler upload failed", String.Format ("Unrecognized response: {0}", line));
                     last_upload_failed_logged = now;
                 }
-                state = State.IDLE;
+                
+                state = State.Idle;
             }
         }
 
@@ -385,7 +388,7 @@
             return ((int) (DateTime.UtcNow - new DateTime (1970, 1, 1)).TotalSeconds).ToString ();
         }
         
-        void Handshake ()
+        private void Handshake ()
         {
             string timestamp = UnixTime();
             string security_token = Hyena.CryptoUtil.Md5Encode
@@ -401,18 +404,18 @@
 
             current_web_req = (HttpWebRequest) WebRequest.Create (uri);
 
-            state = State.WAITING_FOR_HANDSHAKE_RESP;
+            state = State.WaitingForHandshakeResp;
             current_async_result = current_web_req.BeginGetResponse (HandshakeGetResponse, null);
             if (current_async_result == null) {
                 next_interval = DateTime.Now + new TimeSpan (0, 0, hard_failure_retry_sec);
                 hard_failures++;
                 if (hard_failure_retry_sec < MAX_RETRY_SECONDS)
                     hard_failure_retry_sec *= 2;
-                state = State.NEED_HANDSHAKE;
+                state = State.NeedHandshake;
             }
         }
 
-        void HandshakeGetResponse (IAsyncResult ar)
+        private void HandshakeGetResponse (IAsyncResult ar)
         {
             bool success = false;
             bool hard_failure = false;
@@ -425,7 +428,7 @@
                 Hyena.Log.Warning ("Failed to handshake: {0}", e.ToString (), false);
 
                 /* back off for a time before trying again */
-                state = State.IDLE;
+                state = State.Idle;
                 next_interval = DateTime.Now + new TimeSpan (0, 0, RETRY_SECONDS);
                 return;
             }
@@ -440,22 +443,18 @@
             if (line.StartsWith ("BANNED")) {
                 Hyena.Log.Warning ("Audioscrobbler sign-on failed", "Player is banned", false);
                                    
-            }
-            else if (line.StartsWith ("BADAUTH")) {
-                // FIXME: Show to user? :s
-                Hyena.Log.Warning ("Audioscrobbler sign-on failed", "Unrecognized user/password");
-            }
-            else if (line.StartsWith ("BADTIME")) {
+            } else if (line.StartsWith ("BADAUTH")) {
+                Hyena.Log.Warning ("Audioscrobbler sign-on failed", Catalog.GetString ("Last.fm username or password is invalid."));
+                LastfmCore.Account.CryptedPassword = null;
+            } else if (line.StartsWith ("BADTIME")) {
                 Hyena.Log.Warning ("Audioscrobbler sign-on failed", 
                                                   "timestamp provided was not close enough to the current time", false);
-            }
-            else if (line.StartsWith ("FAILED")) {
+            } else if (line.StartsWith ("FAILED")) {
                 Hyena.Log.Warning ("Audioscrobbler sign-on failed",
                                                   String.Format ("Temporary server failure: {0}",
                                                                   line.Substring ("FAILED".Length).Trim()), false);
                 hard_failure = true;
-            }
-            else if (line.StartsWith ("OK")) {
+            } else if (line.StartsWith ("OK")) {
                 success = true;
             } else {
                 Hyena.Log.Error ("Audioscrobbler sign-on failed", 
@@ -472,8 +471,7 @@
                 
                 hard_failures = 0;
                 hard_failure_retry_sec = 60;
-            }
-            else {
+            } else {
                 if (hard_failure == true) {
                     next_interval = DateTime.Now + new TimeSpan (0, 0, hard_failure_retry_sec);
                     hard_failures++;
@@ -482,8 +480,7 @@
                 }
             }
 
-            /* XXX we shouldn't just try to handshake again for BADUSER */
-            state = success ? State.IDLE : State.NEED_HANDSHAKE;
+            state = State.Idle;
         }
         
         //
@@ -498,21 +495,26 @@
         public void NowPlaying (string artist, string title, string album, double duration,
                                 int tracknum, string mbrainzid)
         {
-            if (artist == "" || title == "") {
+            if (String.IsNullOrEmpty(artist) || String.IsNullOrEmpty(title) || !connected) {
                 return;
             }
         
-            string str_track_number = "";
+            string str_track_number = String.Empty;
             if (tracknum != 0) {
                 str_track_number = tracknum.ToString();
             }
             
-            string session_string = String.IsNullOrEmpty(session_id) ? "%session_id%" : session_id;
-            Console.WriteLine ("Session string: {0}", session_string);
+            // Fall back to prefixing the URL with a # in case we haven't actually
+            // authenticated yet. We replace it with the now_playing_url and session_id
+            // later on in NowPlaying(uri).
+            string uriprefix = "#";
+            
+            if (session_id != null) {
+                uriprefix = String.Format ("{0}?s={1}", now_playing_url, session_id);
+            }
             
-            string uri = String.Format ("{0}?s={1}&a={2}&t={3}&b={4}&l={5}&n={6}&m={7}",
-                                        now_playing_url,
-                                        session_string,
+            string uri = String.Format ("{0}&a={1}&t={2}&b={3}&l={4}&n={5}&m={6}",
+                                        uriprefix,
                                         HttpUtility.UrlEncode(artist),
                                         HttpUtility.UrlEncode(title),
 			                            HttpUtility.UrlEncode(album),
@@ -523,30 +525,28 @@
             NowPlaying (uri);
         }
         
-        public void NowPlaying (string uri)
+        private void NowPlaying (string uri)
         {            
             if (now_playing_post != null) {
                 Hyena.Log.DebugFormat ("Now-playing submission already started - aborting.");
                 now_playing_post.Abort ();
             }
             
-            // Fill in placeholder text if NowPlaying was called when
-            // we weren't authenticated.
-            string fillin = "%now_playing_uri%?s=%session_id%";
-            
-            // We prefer not to use replace with placeholders due to security
-            // risks - so we substring to a predetermined length.
-            if (uri.StartsWith (fillin) && session_id != null) {
-                uri = String.Format ("{0}?s={1}&{2}", now_playing_url,
+            // If the URI begins with #, then we know the URI was created before we
+            // had actually authenticated. So, because we didn't know the session_id and
+            // now_playing_url previously, we should now, so we put that in and create our
+            // new URI.
+            if (uri.StartsWith ("#") && session_id != null) {
+                uri = String.Format ("{0}?s={1}{2}", now_playing_url,
                                     session_id,
-                                    uri.Substring (fillin.Length + 1));
+                                    uri.Substring (1));
             }
             
-            now_playing_uri = uri;
+            current_now_playing_uri = uri;
             
             if (session_id == null) {
                 // Go connect - we'll come back later in main timer loop.
-                Connect ();
+                Start ();
                 return;
             }
 
@@ -557,17 +557,16 @@
                 now_playing_post.ContentType = "application/x-www-form-urlencoded";
                 now_playing_post.ContentLength = uri.Length;
                 now_playing_post.BeginGetResponse (NowPlayingGetResponse, null);
-                state = State.WAITING_FOR_RESP;
             } catch (Exception ex) {
                 Hyena.Log.Warning ("Audioscrobbler NowPlaying failed",
                                   String.Format ("Exception while creating request: {0}", ex), false);
                 
-                // Reset now_playing_uri if it was the problem.
-                now_playing_uri = null;
+                // Reset current_now_playing_uri if it was the problem.
+                current_now_playing_uri = null;
             }
         }
 
-        void NowPlayingGetResponse (IAsyncResult ar)
+        private void NowPlayingGetResponse (IAsyncResult ar)
         {
             try {
                 WebResponse my_resp = now_playing_post.EndGetResponse (ar);
@@ -585,35 +584,32 @@
                     /* attempt to re-handshake on the next interval */
                     session_id = null;
                     next_interval = DateTime.Now + new TimeSpan (0, 0, RETRY_SECONDS);
-                    state = State.NEED_HANDSHAKE;
+                    state = State.NeedHandshake;
+                    StartTransitionHandler ();
                     return;
-                }
-                else if (line.StartsWith ("OK")) {
+                } else if (line.StartsWith ("OK")) {
                     // NowPlaying submitted  
                     Hyena.Log.DebugFormat ("Submitted NowPlaying track to Audioscrobbler");
                     now_playing_post = null;
-                    now_playing_uri = null;
-                    state = State.IDLE;
+                    current_now_playing_uri = null;
                     return;
-                }
-                else {
+                } else {
                     Hyena.Log.Warning ("Audioscrobbler NowPlaying failed", "Unexpected or no response", false);       
                 }
             }
             catch (Exception e) {
-                Hyena.Log.Error ("Audioscrobbler NowPlaying failed", 
+                Hyena.Log.Warning ("Audioscrobbler NowPlaying failed", 
                               String.Format("Failed to post NowPlaying: {0}", e), false);
             }
             
             // NowPlaying error/success is non-crutial.
             hard_failures++;
             if (hard_failures < 3) {
-                NowPlaying (now_playing_uri);
+                NowPlaying (current_now_playing_uri);
             } else {
                 // Give up - NowPlaying status information is non-critical.
-                now_playing_uri = null;
+                current_now_playing_uri = null;
                 now_playing_post = null;
-                state = State.IDLE;
             }
         }
     }

Modified: trunk/banshee/src/Libraries/Mono.Media/Media.Playlists.Xspf/Track.cs
==============================================================================
--- trunk/banshee/src/Libraries/Mono.Media/Media.Playlists.Xspf/Track.cs	(original)
+++ trunk/banshee/src/Libraries/Mono.Media/Media.Playlists.Xspf/Track.cs	Fri Feb 29 06:09:27 2008
@@ -49,6 +49,8 @@
         
         private Playlist parent;
         
+        private XmlNode ctor_node;
+        
         public Track()
         {
         }
@@ -68,6 +70,8 @@
             
             LoadBase(node, xmlns);
             
+            ctor_node = node;
+            
             album = XmlUtil.ReadString(node, xmlns, "xspf:album");
 
             track_num = XmlUtil.ReadUInt(node, xmlns, "xspf:trackNum");
@@ -90,6 +94,18 @@
             }
         }
         
+        // XXX: Better solution could probably be achieved?
+        public string GetExtendedValue (string key)
+        {
+            foreach (XmlNode n in ctor_node) {
+                if (n.LocalName == key) {                    
+                    return n.InnerText;
+                }
+            }
+            
+            return null;
+        }
+        
         public Uri GetLocationAt(int position)
         {
             return locations[position];



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]