1 /***************************************************************************
2 * Copyright (C) 2008 by Andrzej Rybczak *
3 * electricityispower@gmail.com *
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 2 of the License, or *
8 * (at your option) any later version. *
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. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
21 #include <curl/curl.h>
34 extern Handshake myHandshake
;
36 std::deque
<std::string
> MPD::Song::Queue
;
38 MPD::Song::Song() : Data(0),
51 void MPD::Song::Clear()
61 void MPD::Song::SetData(mpd_Song
*song
)
68 itsIsStream
= strncmp("http://", Data
->file
, 7) == 0;
71 void MPD::Song::Submit()
77 Data
->time
= Playback
;
89 if (myHandshake
.Status
!= "OK" || myHandshake
.SubmissionURL
.empty())
91 Log(llInfo
, "Problem with handshake, queue song at position %d...", Song::Queue
.size());
97 Log(llInfo
, "Submitting song...");
99 std::ostringstream postdata
;
100 string result
, postdata_str
;
103 char *c_artist
= curl_easy_escape(0, Data
->artist
, 0);
104 char *c_title
= curl_easy_escape(0, Data
->title
, 0);
105 char *c_album
= Data
->album
? curl_easy_escape(0, Data
->album
, 0) : NULL
;
106 char *c_track
= Data
->track
? curl_easy_escape(0, Data
->track
, 0) : NULL
;
109 << "s=" << myHandshake
.SessionID
110 << "&a[0]=" << c_artist
111 << "&t[0]=" << c_title
112 << "&i[0]=" << StartTime
115 << "&l[0]=" << Data
->time
119 postdata
<< "&n[0]=";
122 postdata
<< "&m[0]=";
129 postdata_str
= postdata
.str();
131 Log(llVerbose
, "URL: %s", myHandshake
.SubmissionURL
.c_str());
132 Log(llVerbose
, "Post data: %s", postdata_str
.c_str());
134 CURL
*submission
= curl_easy_init();
135 curl_easy_setopt(submission
, CURLOPT_URL
, myHandshake
.SubmissionURL
.c_str());
136 curl_easy_setopt(submission
, CURLOPT_POST
, 1);
137 curl_easy_setopt(submission
, CURLOPT_POSTFIELDS
, postdata_str
.c_str());
138 curl_easy_setopt(submission
, CURLOPT_WRITEFUNCTION
, write_data
);
139 curl_easy_setopt(submission
, CURLOPT_WRITEDATA
, &result
);
140 curl_easy_setopt(submission
, CURLOPT_CONNECTTIMEOUT
, curl_timeout
);
141 code
= curl_easy_perform(submission
);
142 curl_easy_cleanup(submission
);
144 IgnoreNewlines(result
);
148 Log(llInfo
, "Song submitted.");
154 Log(llInfo
, "Error while submitting song: %s", curl_easy_strerror(code
));
158 Log(llInfo
, "Audioscrobbler returned status %s", result
.c_str());
159 myHandshake
.Clear(); // handshake probably failed if we are here, so reset it
160 Log(llVerbose
, "Handshake reset");
168 void MPD::Song::Cache()
170 std::ostringstream cache
;
173 char *c_artist
= curl_easy_escape(0, Data
->artist
, 0);
174 char *c_title
= curl_easy_escape(0, Data
->title
, 0);
175 char *c_album
= Data
->album
? curl_easy_escape(0, Data
->album
, 0) : NULL
;
176 char *c_track
= Data
->track
? curl_easy_escape(0, Data
->track
, 0) : NULL
;
179 << "&a[" << Song::Queue
.size() << "]=" << c_artist
180 << "&t[" << Song::Queue
.size() << "]=" << c_title
181 << "&i[" << Song::Queue
.size() << "]=" << StartTime
182 << "&o[" << Song::Queue
.size() << "]=P"
183 << "&r[" << Song::Queue
.size() << "]="
184 << "&l[" << Song::Queue
.size() << "]=" << Data
->time
185 << "&b[" << Song::Queue
.size() << "]=";
188 cache
<< "&n[" << Song::Queue
.size() << "]=";
191 cache
<< "&m[" << Song::Queue
.size() << "]=";
193 cache_str
= cache
.str();
195 Log(llVerbose
, "Metadata: %s", cache_str
.c_str());
202 WriteCache(cache_str
);
203 Song::Queue
.push_back(cache_str
);
204 Log(llInfo
, "Song cached.");
207 bool MPD::Song::isStream() const
212 bool MPD::Song::canBeSubmitted()
214 if (!StartTime
|| Data
->time
< 30 || !Data
->artist
|| !Data
->title
)
218 Log(llInfo
, "Song's start time wasn't known, not submitting.");
220 else if (Data
->time
< 30)
222 Log(llInfo
, "Song's length is too short, not submitting.");
224 else if (!Data
->artist
|| !Data
->title
)
226 Log(llInfo
, "Song has missing tags, not submitting.");
230 else if (Playback
< 4*60 && Playback
< Data
->time
/2)
232 Log(llInfo
, "Noticed playback was too short, not submitting.");
238 void MPD::Song::GetCached()
240 std::ifstream
f(Config
.file_cache
.c_str());
248 Queue
.push_back(line
);
253 void MPD::Song::SendQueue()
255 if (Song::Queue
.empty())
258 Log(llInfo
, "Queue is not empty, submitting songs...");
260 string result
, postdata
;
264 postdata
+= myHandshake
.SessionID
;
266 for (std::deque
<string
>::const_iterator it
= Song::Queue
.begin(); it
!= Song::Queue
.end(); it
++)
269 Log(llVerbose
, "URL: %s", myHandshake
.SubmissionURL
.c_str());
270 Log(llVerbose
, "Post data: %s", postdata
.c_str());
272 CURL
*submission
= curl_easy_init();
273 curl_easy_setopt(submission
, CURLOPT_URL
, myHandshake
.SubmissionURL
.c_str());
274 curl_easy_setopt(submission
, CURLOPT_POST
, 1);
275 curl_easy_setopt(submission
, CURLOPT_POSTFIELDS
, postdata
.c_str());
276 curl_easy_setopt(submission
, CURLOPT_WRITEFUNCTION
, write_data
);
277 curl_easy_setopt(submission
, CURLOPT_WRITEDATA
, &result
);
278 curl_easy_setopt(submission
, CURLOPT_CONNECTTIMEOUT
, curl_timeout
);
279 code
= curl_easy_perform(submission
);
280 curl_easy_cleanup(submission
);
282 IgnoreNewlines(result
);
286 Log(llInfo
, "Number of submitted songs: %d", Song::Queue
.size());
294 Log(llInfo
, "Error while submitting songs: %s", curl_easy_strerror(code
));
298 Log(llInfo
, "Audioscrobbler returned status %s", result
.c_str());