PageRenderTime 63ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/lastfm-sharp/Scrobbling/Connection.cs

https://github.com/tjom/MIRPCADB
C# | 191 lines | 107 code | 27 blank | 57 comment | 5 complexity | 08a965df4dea0a6595e56c6e59900f91 MD5 | raw file
  1. // Connection.cs
  2. //
  3. // Copyright (C) 2009 Amr Hassan
  4. //
  5. // This program is free software: you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation, either version 3 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. //
  18. using System;
  19. namespace Lastfm.Scrobbling
  20. {
  21. /// <summary>
  22. /// A connection to the Last.fm scrobbling service. Can be used individually for scrobbling
  23. /// or through a <see cref="ScrobbleManager"/> object.
  24. /// </summary>
  25. public class Connection
  26. {
  27. public string ClientID {get; private set;}
  28. private string SessionID {get; set;}
  29. private Uri SubmissionURL {get; set;}
  30. private Uri NowplayingURL {get; set;}
  31. private RequestParameters handshakeParameters;
  32. private bool firstHandshakeDone {get; set;}
  33. public Connection(string clientID, string clientVersion, string username,
  34. Lastfm.Services.Session authenticatedSession)
  35. {
  36. RequestParameters p = new RequestParameters();
  37. p["hs"] = "true";
  38. p["p"] = "1.2.1";
  39. p["c"] = clientID;
  40. p["v"] = clientVersion;
  41. p["u"] = username;
  42. string timestamp = Utilities.DateTimeToUTCTimestamp(DateTime.Now).ToString();
  43. p["t"] = timestamp;
  44. p["api_key"] = authenticatedSession.APIKey;
  45. p["sk"] = authenticatedSession.SessionKey;
  46. p["a"] = Utilities.md5(authenticatedSession.APISecret + timestamp);
  47. this.handshakeParameters = p;
  48. ClientID = clientID;
  49. }
  50. public Connection(string clientID, string clientVersion, string username, string md5Password)
  51. {
  52. RequestParameters p = new RequestParameters();
  53. p["hs"] = "true";
  54. p["p"] = "1.2.1";
  55. p["c"] = clientID;
  56. p["v"] = clientVersion;
  57. p["u"] = username;
  58. string timestamp = Utilities.DateTimeToUTCTimestamp(DateTime.Now).ToString();
  59. p["t"] = timestamp;
  60. p["a"] = Utilities.md5(md5Password + timestamp);
  61. this.handshakeParameters = p;
  62. ClientID = clientID;
  63. }
  64. /// <summary>
  65. /// A handshake is performed at the beginning to retrieve the
  66. /// SessionID, SubmissionURL and NowplayingURL and also everytime the server
  67. /// reports that the SessionID is invalid.
  68. /// </summary>
  69. private void doHandshake()
  70. {
  71. Request request = new Request(new Uri("http://post.audioscrobbler.com:80/"), handshakeParameters);
  72. string[] response = request.execute().Split('\n');
  73. SessionID = response[1];
  74. NowplayingURL = new Uri(response[2]);
  75. SubmissionURL = new Uri(response[3]);
  76. }
  77. /// <summary>
  78. /// Performs the initial handshake. Can be ignored, a handshake
  79. /// will be performed whenever necessary.
  80. /// </summary>
  81. public void Initialize()
  82. {
  83. if (!firstHandshakeDone)
  84. {
  85. doHandshake();
  86. firstHandshakeDone = true;
  87. }
  88. }
  89. /// <summary>
  90. /// Send the now playing notification.
  91. /// </summary>
  92. /// <param name="track">
  93. /// A <see cref="NowplayingTrack"/>
  94. /// </param>
  95. public void ReportNowplaying(NowplayingTrack track)
  96. {
  97. Initialize();
  98. RequestParameters p = new RequestParameters();
  99. p["s"] = SessionID;
  100. p["a"] = track.Artist;
  101. p["t"] = track.Title;
  102. p["b"] = track.Album;
  103. if (track.Duration.TotalSeconds == 0)
  104. p["l"] = "";
  105. else
  106. p["l"] = track.Duration.TotalSeconds.ToString();
  107. if (track.Number == 0)
  108. p["n"] = "";
  109. else
  110. p["n"] = track.Number.ToString();
  111. p["m"] = track.MBID;
  112. Request request = new Request(this.NowplayingURL, p);
  113. // A BadSessionException occurs when another client has made a handshake
  114. // with this user's credentials, should redo a handshake and pass this
  115. // exception quietly.
  116. try
  117. {
  118. request.execute();
  119. } catch (BadSessionException) {
  120. this.doHandshake();
  121. this.ReportNowplaying(track);
  122. }
  123. }
  124. /// <summary>
  125. /// Public scrobble function. Scrobbles a PlayedTrack object.
  126. /// </summary>
  127. /// <param name="track">
  128. /// A <see cref="PlayedTrack"/>
  129. /// </param>
  130. public void Scrobble(Entry track)
  131. {
  132. RequestParameters np = new RequestParameters();
  133. RequestParameters p = track.getParameters();
  134. foreach(string key in p.Keys)
  135. np[key + "[0]"] = p[key];
  136. // This scrobbles the collection of parameters no matter what they belong to.
  137. this.Scrobble(np);
  138. }
  139. /// <summary>
  140. /// The internal scrobble function, scrobbles pure request parameters.
  141. /// Could be for more than one track, as specified by Last.fm, but they recommend that
  142. /// only one track should be submitted at a time.
  143. /// </summary>
  144. /// <param name="parameters">
  145. /// A <see cref="RequestParameters"/>
  146. /// </param>
  147. internal void Scrobble(RequestParameters parameters)
  148. {
  149. Initialize();
  150. parameters["s"] = SessionID;
  151. Request request = new Request(this.SubmissionURL, parameters);
  152. // A BadSessionException occurs when another client has made a handshake
  153. // with this user's credentials, should redo a handshake and pass this
  154. // exception quietly.
  155. try
  156. {
  157. request.execute();
  158. } catch (BadSessionException) {
  159. this.doHandshake();
  160. this.Scrobble(parameters);
  161. }
  162. }
  163. }
  164. }