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
- From: ahixon svn gnome org
- To: svn-commits-list gnome org
- Subject: 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
- Date: Fri, 29 Feb 2008 06:09:27 +0000 (GMT)
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]