49
52
public class LastfmData<T> : IEnumerable<T> where T : DataEntry
51
protected DataEntryCollection<T> collection;
54
private static DataEntryCollection<T> empty_collection = new DataEntryCollection<T> ((XmlNodeList)null);
55
protected DataEntryCollection<T> collection = empty_collection;
52
56
protected XmlDocument doc;
53
57
protected string data_url;
54
58
protected string cache_file;
72
76
DataCore.Initialize ();
74
this.data_url = HostInjectionHack (String.Format ("http://ws.audioscrobbler.com/1.0/{0}", dataUrlFragment));
75
this.cache_file = GetCachedPathFromUrl (data_url);
78
this.data_url = DataCore.FixLastfmUrl (String.Format ("http://ws.audioscrobbler.com/1.0/{0}", dataUrlFragment));
79
this.cache_file = DataCore.GetCachedPathFromUrl (data_url);
76
80
this.cache_duration = cacheDuration;
77
81
this.xpath = xpath;
90
94
private void GetData ()
92
96
// Download the content if necessary
97
DataCore.DownloadContent (data_url, cache_file, cache_duration);
95
99
// Load the XML from the new or cached local file
96
100
doc = new XmlDocument ();
134
138
#region Private methods
136
private void DownloadContent ()
138
// See if we have a valid cached copy
139
if (cache_duration != CacheDuration.None) {
140
if (File.Exists (cache_file)) {
141
DateTime last_updated_time = File.GetLastWriteTime (cache_file);
142
if (cache_duration == CacheDuration.Infinite || DateTime.Now - last_updated_time < DataCore.NormalCacheTime) {
148
HttpWebRequest request = (HttpWebRequest) WebRequest.Create (data_url);
149
request.UserAgent = DataCore.UserAgent;
150
request.KeepAlive = false;
152
using (HttpWebResponse response = (HttpWebResponse) request.GetResponse ()) {
153
using (Stream stream = GetResponseStream (response)) {
154
using (FileStream file_stream = File.Open (cache_file, FileMode.Create)) {
155
using (BufferedStream buffered_stream = new BufferedStream (file_stream)) {
156
byte [] buffer = new byte[8192];
160
read = stream.Read (buffer, 0, buffer.Length);
165
buffered_stream.Write (buffer, 0, read);
173
private static Stream GetResponseStream (HttpWebResponse response)
175
return response.ContentEncoding == "gzip"
176
? new GZipInputStream (response.GetResponseStream ())
177
: response.GetResponseStream ();
181
private static string GetCachedPathFromUrl (string url)
183
string hash = url.GetHashCode ().ToString ("X").ToLower ();
184
return Path.Combine (Path.Combine (DataCore.CachePath, hash.Substring (0, 2)), hash);
187
// FIXME: This is to (try to) work around a bug in last.fm's XML
188
// Some XML nodes with URIs as content do not return a URI with a
189
// host name. It appears that in these cases the hostname is to be
190
// static3.last.fm, but it may not always be the case - this is
191
// a bug in last.fm, but we attempt to work around it here
192
// http://bugzilla.gnome.org/show_bug.cgi?id=408068
194
private static string HostInjectionHack (string url)
196
if (url.StartsWith ("http:///storable/")) {
197
url = url.Insert (7, "static3.last.fm");