<commit_before>#include "mpdas.h"

#define ROOTURL		"http://ws.audioscrobbler.com/2.0/"
#define APIKEY		"<KEY>"
#define	SECRET		"<KEY>"

CAudioScrobbler* AudioScrobbler = 0;

#define CLEANUP()	_response.clear()

size_t
writecb(void* ptr, size_t size, size_t nmemb, void *stream)
{
	AudioScrobbler->ReportResponse((char*)ptr, size*nmemb);
}

CAudioScrobbler::CAudioScrobbler()
{
	_failcount = 0;
	_authed = false;
	_response = "";
	_handle = curl_easy_init();
	if(!_handle) {
		eprintf("%s", "Could not initialize CURL.");
		exit(EXIT_FAILURE);
	}
}

void
CAudioScrobbler::OpenURL(std::string url, const char* postfields = 0, char* errbuf = 0)
{
	curl_easy_setopt(_handle, CURLOPT_DNS_CACHE_TIMEOUT, 0);
	curl_easy_setopt(_handle, CURLOPT_NOPROGRESS, 1);
	curl_easy_setopt(_handle, CURLOPT_WRITEFUNCTION, writecb);

	if(postfields) {
		curl_easy_setopt(_handle, CURLOPT_POST, 1);
		curl_easy_setopt(_handle, CURLOPT_POSTFIELDS, postfields);
	}
	else
		curl_easy_setopt(_handle, CURLOPT_POST, 0);
	if(errbuf)
		curl_easy_setopt(_handle, CURLOPT_ERRORBUFFER, errbuf);
	
	curl_easy_setopt(_handle, CURLOPT_URL, url.c_str());
	curl_easy_perform(_handle);
}


void
CAudioScrobbler::ReportResponse(char* buf, size_t size)
{
	_response.append(buf);
}

std::string
CAudioScrobbler::CreateScrobbleMessage(int index, centry_t* entry)
{
	std::ostringstream msg, sigmsg ;
	std::string artist, title, album, array = "=";

	char* temp = 0;
	temp = curl_easy_escape(_handle, entry->artist.c_str(), entry->artist.length());
	artist = temp;
	curl_free(temp);
	temp = curl_easy_escape(_handle, entry->title.c_str(), entry->title.length());
	title = temp;
	curl_free(temp);
	temp = curl_easy_escape(_handle, entry->album.c_str(), entry->album.length());
	album = temp;
	curl_free(temp);

	msg << "&album" << array << album;
	msg << "&api_key=" << APIKEY;
	msg << "&artist" << array << artist;
	msg << "&duration" << array << entry->time;
	msg << "&method=track.Scrobble";
	msg << "&timestamp" << array << entry->starttime;
	msg << "&track" << array << title;
	msg << "&sk=" << _sessionid;

	array = "";

	sigmsg << "album" << array << entry->album;
	sigmsg << "api_key" << APIKEY;
	sigmsg << "artist" << array << entry->artist;
	sigmsg << "duration" << array << entry->time;
	sigmsg << "methodtrack.Scrobble";
	sigmsg << "sk" << _sessionid;
	sigmsg << "timestamp" << array << entry->starttime;
	sigmsg << "track" << array << entry->title;
	sigmsg << SECRET;

	std::string sighash(md5sum((char*)"%s", sigmsg.str().c_str()));
	msg << "&api_sig=" << sighash;

	return msg.str();
}

void
CAudioScrobbler::Failure()
{
	_failcount += 1;
	if(_failcount >= 3) {
		eprintf("%s", "Re-Handshaking!");
		_failcount = 0;
		Handshake();
	}
}

bool
CAudioScrobbler::CheckFailure(std::string response)
{
	bool retval = false;

	size_t start, end;
	start = _response.find("<error code=\"")+13;
	end = _response.find(">", start)-1;
	std::string errorcode = _response.substr(start, end-start);
	int code = strtol(errorcode.c_str(), 0, 10);

	eprintf("%s%i", "Code: ", code);

	return retval;
}

bool
CAudioScrobbler::Scrobble(centry_t* entry)
{
	bool retval = false;
	if(!_authed) {
		eprintf("Handshake hasn't been done yet.");
		Handshake();
		return retval;
	}
	iprintf("Scrobbling: %s - %s", entry->artist.c_str(), entry->title.c_str());
	
	OpenURL(ROOTURL, CreateScrobbleMessage(0, entry).c_str());
	if(_response.find("<lfm status=\"ok\">") != std::string::npos) {
		iprintf("%s", "Scrobbled successfully.");
		retval = true;<commit_msg>improve error handling and verbose output<commit_after>#include "mpdas.h"

#define ROOTURL		"http://ws.audioscrobbler.com/2.0/"
#define APIKEY		"<KEY>"
#define	SECRET		"<KEY>"

CAudioScrobbler* AudioScrobbler = 0;

#define CLEANUP()	_response.clear()

size_t
writecb(void* ptr, size_t size, size_t nmemb, void *stream)
{
	AudioScrobbler->ReportResponse((char*)ptr, size*nmemb);
}

CAudioScrobbler::CAudioScrobbler()
{
	_failcount = 0;
	_authed = false;
	_response = "";
	_handle = curl_easy_init();
	if(!_handle) {
		eprintf("%s", "Could not initialize CURL.");
		exit(EXIT_FAILURE);
	}
}

void
CAudioScrobbler::OpenURL(std::string url, const char* postfields = 0, char* errbuf = 0)
{
	curl_easy_setopt(_handle, CURLOPT_DNS_CACHE_TIMEOUT, 0);
	curl_easy_setopt(_handle, CURLOPT_NOPROGRESS, 1);
	curl_easy_setopt(_handle, CURLOPT_WRITEFUNCTION, writecb);

	if(postfields) {
		curl_easy_setopt(_handle, CURLOPT_POST, 1);
		curl_easy_setopt(_handle, CURLOPT_POSTFIELDS, postfields);
	}
	else
		curl_easy_setopt(_handle, CURLOPT_POST, 0);
	if(errbuf)
		curl_easy_setopt(_handle, CURLOPT_ERRORBUFFER, errbuf);
	
	curl_easy_setopt(_handle, CURLOPT_URL, url.c_str());
	curl_easy_perform(_handle);
}


void
CAudioScrobbler::ReportResponse(char* buf, size_t size)
{
	_response.append(buf);
}

std::string
CAudioScrobbler::CreateScrobbleMessage(int index, centry_t* entry)
{
	std::ostringstream msg, sigmsg ;
	std::string artist, title, album, array = "=";

	char* temp = 0;
	temp = curl_easy_escape(_handle, entry->artist.c_str(), entry->artist.length());
	artist = temp;
	curl_free(temp);
	temp = curl_easy_escape(_handle, entry->title.c_str(), entry->title.length());
	title = temp;
	curl_free(temp);
	temp = curl_easy_escape(_handle, entry->album.c_str(), entry->album.length());
	album = temp;
	curl_free(temp);

	msg << "&album" << array << album;
	msg << "&api_key=" << APIKEY;
	msg << "&artist" << array << artist;
	msg << "&duration" << array << entry->time;
	msg << "&method=track.Scrobble";
	msg << "&timestamp" << array << entry->starttime;
	msg << "&track" << array << title;
	msg << "&sk=" << _sessionid;

	array = "";

	sigmsg << "album" << array << entry->album;
	sigmsg << "api_key" << APIKEY;
	sigmsg << "artist" << array << entry->artist;
	sigmsg << "duration" << array << entry->time;
	sigmsg << "methodtrack.Scrobble";
	sigmsg << "sk" << _sessionid;
	sigmsg << "timestamp" << array << entry->starttime;
	sigmsg << "track" << array << entry->title;
	sigmsg << SECRET;

	std::string sighash(md5sum((char*)"%s", sigmsg.str().c_str()));
	msg << "&api_sig=" << sighash;

	return msg.str();
}

void
CAudioScrobbler::Failure()
{
	_failcount += 1;
	if(_failcount >= 3) {
		eprintf("%s", "Re-Handshaking!");
		_failcount = 0;
		Handshake();
	}
}

bool
CAudioScrobbler::CheckFailure(std::string response)
{
	bool retval = false;

	size_t start, end;
	start = _response.find("<error code=\"")+13;
	end = _response.find(">", start)-1;
	std::string errorcode = _response.substr(start, end-start);
	int code = strtol(errorcode.c_str(), 0, 10);

	eprintf("%s%i", "Code: ", code);

	switch(code) {
		case 3:
			eprintf("Invalid Method. This should not happen.");
			retval = true;
			break;
		case 4:
			eprintf("Authentification failed. Please check your login data.");
			exit(EXIT_FAILURE);
		case 9:
			eprintf("Invalid session key. Reauthentificating.");
			retval = true;
			_failcount = 3;
			break;
		case 10:
			eprintf("Invalid API-Key. Let's bugger off.");
			exit(EXIT_FAILURE);
		case 16:
			eprintf("The service is temporarily unavailable, we will try again later..");
			retval = true;
			break;
		case 26:
			eprintf("Uh oh. Suspended API key - Access for your account has been suspended, please contact Last.fm");
			exit(EXIT_FAILURE);
	}

	return retval;
}

bool
CAudioScrobbler::Scrobble(centry_t* entry)
{
	bool retval = false;
	if(!_authed) {
		eprintf("Handshake hasn't been done yet.");
		Handshake();
		return retval;
	}
	iprintf("Scrobbling: %s - %s", entry->artist.c_str(), entry->title.c_str());
	
	OpenURL(ROOTURL, CreateScrobbleMessage(0, entry).c_str());
	if(_response.find("<lfm status=\"ok\">") != std::string::npos) {
		iprintf("%s", "Scrobbled successfully.");
		retval = true;
{'fraction_non_alphanumeric': 0.17574578469520102, 'fraction_numerical': 0.007003891050583658, 'mean_word_length': 5.188603531300161, 'pattern_counts': {'":': 0, '<': 183, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 1, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5350993', 'n_tokens_mistral': 3147, 'n_tokens_neox': 2944, 'n_words': 602}