/* sfdb_freesound_mootcher.cpp **********************************************************************\r
- \r
+\r
Adapted for Ardour by Ben Loftis, March 2008\r
- \r
+ Updated to new Freesound API by Colin Fletcher, November 2011\r
+\r
Mootcher 23-8-2005\r
\r
Mootcher Online Access to thefreesoundproject website\r
#include "sfdb_freesound_mootcher.h"\r
\r
#include "pbd/xml++.h"\r
+#include "pbd/filesystem.h"\r
\r
#include <sys/stat.h>\r
#include <sys/types.h>\r
+#include <iostream>\r
+\r
+#include <glib.h>\r
+#include <glib/gstdio.h>\r
+\r
+#include "i18n.h"\r
\r
#include "ardour/audio_library.h"\r
\r
-#define TRUE 1\r
+static const std::string base_url = "http://www.freesound.org/api";\r
+static const std::string api_key = "9d77cb8d841b4bcfa960e1aae62224eb"; // ardour3\r
+\r
\r
//------------------------------------------------------------------------\r
-Mootcher:: Mootcher(const char *saveLocation)\r
- : curl( NULL )\r
- , connection( 0 )\r
+Mootcher::Mootcher()\r
+ : curl(curl_easy_init())\r
{\r
- changeWorkingDir(saveLocation);\r
+ std::string path;\r
+ path = Glib::get_home_dir() + "/Freesound/";\r
+ changeWorkingDir ( path.c_str() );\r
};\r
//------------------------------------------------------------------------\r
-Mootcher:: ~Mootcher()\r
+Mootcher:: ~Mootcher()\r
{\r
- remove( "cookiejar.txt" );\r
+ curl_easy_cleanup(curl);\r
}\r
+\r
//------------------------------------------------------------------------\r
-const char* Mootcher::changeWorkingDir(const char *saveLocation)\r
+void Mootcher::changeWorkingDir(const char *saveLocation)\r
{\r
basePath = saveLocation;\r
#ifdef __WIN32__\r
std::string replace = "/";\r
- int pos = (int)basePath.find("\\");\r
+ size_t pos = basePath.find("\\");\r
while( pos != std::string::npos ){\r
basePath.replace(pos, 1, replace);\r
- pos = (int)basePath.find("\\");\r
+ pos = basePath.find("\\");\r
}\r
#endif\r
- // \r
- int pos2 = basePath.find_last_of("/");\r
+ //\r
+ size_t pos2 = basePath.find_last_of("/");\r
if(basePath.length() != (pos2+1)) basePath += "/";\r
- \r
- // create Freesound directory and sound dir\r
- std::string sndLocation = basePath;\r
- mkdir(sndLocation.c_str(), 0777); \r
- sndLocation += "snd";\r
- mkdir(sndLocation.c_str(), 0777); \r
+}\r
\r
- return basePath.c_str();\r
+void Mootcher::ensureWorkingDir ()\r
+{\r
+ PBD::sys::path p = basePath;\r
+ p /= "snd";\r
+ if (!PBD::sys::is_directory (p)) {\r
+ PBD::sys::create_directories (p);\r
+ }\r
}\r
+ \r
\r
//------------------------------------------------------------------------\r
-size_t Mootcher::WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)\r
+size_t Mootcher::WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)\r
{\r
register int realsize = (int)(size * nmemb);\r
struct MemoryStruct *mem = (struct MemoryStruct *)data;\r
\r
- // There might be a realloc() out there that doesn't like \r
- // reallocing NULL pointers, so we take care of it here\r
- if(mem->memory) mem->memory = (char *)realloc(mem->memory, mem->size + realsize + 1);\r
- else mem->memory = (char *)malloc(mem->size + realsize + 1);\r
+ mem->memory = (char *)realloc(mem->memory, mem->size + realsize + 1);\r
\r
if (mem->memory) {\r
memcpy(&(mem->memory[mem->size]), ptr, realsize);\r
\r
\r
//------------------------------------------------------------------------\r
-void Mootcher::toLog(std::string input)\r
-{\r
-printf("%s\n", input.c_str());// for debugging\r
-}\r
\r
+std::string Mootcher::sortMethodString(enum sortMethod sort) {\r
+// given a sort type, returns the string value to be passed to the API to\r
+// sort the results in the requested way.\r
+\r
+ switch (sort) {\r
+ case sort_duration_desc: return "duration_desc"; \r
+ case sort_duration_asc: return "duration_asc";\r
+ case sort_created_desc: return "created_desc";\r
+ case sort_created_asc: return "created_asc";\r
+ case sort_downloads_desc: return "downloads_desc";\r
+ case sort_downloads_asc: return "downloads_asc";\r
+ case sort_rating_desc: return "rating_desc";\r
+ case sort_rating_asc: return "rating_asc";\r
+ default: return ""; \r
+ }\r
+}\r
\r
//------------------------------------------------------------------------\r
-void Mootcher::setcUrlOptions()\r
+void Mootcher::setcUrlOptions()\r
{\r
// basic init for curl\r
curl_global_init(CURL_GLOBAL_ALL);\r
// some servers don't like requests that are made without a user-agent field, so we provide one\r
curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");\r
// setup curl error buffer\r
- CURLcode res = curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);\r
- // always use the cookie with session id which is received at the login\r
- curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "cookiejar.txt");\r
+ curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);\r
// Allow redirection\r
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);\r
+ \r
+ // Allow connections to time out (without using signals)\r
+ curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);\r
+ curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30);\r
+\r
+\r
}\r
\r
-//------------------------------------------------------------------------\r
-int Mootcher::doLogin(std::string login, std::string password)\r
+std::string Mootcher::doRequest(std::string uri, std::string params)\r
{\r
- if(connection==1)\r
- return 1;\r
- \r
+ std::string result;\r
struct MemoryStruct xml_page;\r
xml_page.memory = NULL;\r
xml_page.size = 0;\r
\r
- // create the post message from the login and password\r
- std::string postMessage;\r
- postMessage += "username=";\r
- postMessage += curl_escape(login.c_str(), 0);\r
- postMessage += "&password=";\r
- postMessage += curl_escape(password.c_str(), 0);\r
- postMessage += "&login=";\r
- postMessage += curl_escape("1", 0);\r
- postMessage += "&redirect=";\r
- postMessage += curl_escape("../tests/login.php", 0);\r
-\r
- // Do the setup for libcurl\r
- curl = curl_easy_init();\r
-\r
- if(curl)\r
- {\r
- setcUrlOptions();\r
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); \r
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&xml_page);\r
- // save the sessoin id that is given back by the server in a cookie\r
- curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "cookiejar.txt");\r
- // use POST for login variables\r
- curl_easy_setopt(curl, CURLOPT_POST, TRUE);\r
- curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postMessage.c_str());\r
- curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, -1);\r
-\r
- // the url to get\r
- std::string login_url = "http://www.freesound.org/forum/login.php";\r
- curl_easy_setopt(curl, CURLOPT_URL, login_url.c_str() );\r
-\r
- // perform online request\r
- connection = 1;\r
- CURLcode res = curl_easy_perform(curl);\r
- if( res != 0 ) {\r
- toLog("curl login error\n");\r
- toLog(curl_easy_strerror(res));\r
- connection = 0;\r
- }\r
- \r
- if (connection == 1){\r
- std::string check_page = xml_page.memory;\r
- int test = (int)check_page.find("login"); //logged\r
- if( strcmp(xml_page.memory, "login") == 0 )\r
- toLog("Logged in.\n");\r
- else {\r
- toLog("Login failed: Check username and password.\n");\r
- connection = 0;\r
- }\r
- }\r
+ setcUrlOptions();\r
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);\r
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &xml_page);\r
\r
- // free the memory\r
- if(xml_page.memory){ \r
- free( xml_page.memory );\r
- xml_page.memory = NULL;\r
- xml_page.size = 0;\r
- }\r
+ // curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);\r
+ // curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postMessage.c_str());\r
+ // curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, -1);\r
\r
- std::cerr << "Login was cool, connection = " << connection << std::endl;\r
- return connection;\r
+ // the url to get\r
+ std::string url = base_url + uri + "?";\r
+ if (params != "") {\r
+ url += params + "&api_key=" + api_key + "&format=xml";\r
+ } else {\r
+ url += "api_key=" + api_key + "&format=xml";\r
}\r
- else return 3; // will be returned if a curl related problem ocurrs\r
-}\r
-//------------------------------------------------------------------------\r
-std::string Mootcher::searchText(std::string word)\r
-{\r
- struct MemoryStruct xml_page;\r
- xml_page.memory = NULL;\r
- xml_page.size = 0;\r
- \r
- std::string result;\r
-\r
- if(connection != 0)\r
- {\r
- // create a url encoded post message\r
- std::string postMessage;\r
- char tempString[ 128 ];\r
- char *tempPointer = &tempString[0];\r
-\r
- postMessage = "search=";\r
- postMessage += curl_escape(word.c_str(), 0);\r
- sprintf( tempPointer, "&searchDescriptions=1");\r
- postMessage += tempPointer;\r
- sprintf( tempPointer, "&searchtags=1");\r
- postMessage += tempPointer;\r
-\r
- // Ref: http://www.freesound.org/forum/viewtopic.php?p=19081\r
- // const ORDER_DEFAULT = 0;\r
- // const ORDER_DOWNLOADS_DESC = 1;\r
- // const ORDER_DOWNLOADS_ASC = 2;\r
- // const ORDER_USERNAME_DESC = 3;\r
- // const ORDER_USERNAME_ASC = 4;\r
- // const ORDER_DATE_DESC = 5;\r
- // const ORDER_DATE_ASC = 6;\r
- // const ORDER_DURATION_DESC = 7;\r
- // const ORDER_DURATION_ASC = 8;\r
- // const ORDER_FILEFORMAT_DESC = 9;\r
- // const ORDER_FILEFORMAT_ASC = 10;\r
- sprintf( tempPointer, "&order=1");\r
- postMessage += tempPointer;\r
- sprintf( tempPointer, "&start=0");\r
- postMessage += tempPointer;\r
- sprintf( tempPointer, "&limit=10");\r
- postMessage += tempPointer;\r
- // The limit of 10 samples is arbitrary, but seems\r
- // reasonable in light of the fact that all of the returned\r
- // samples get downloaded, and downloads are s-l-o-w.\r
\r
- if(curl)\r
- {\r
- // basic init for curl \r
- setcUrlOptions(); \r
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); \r
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&xml_page);\r
- // setup the post message\r
- curl_easy_setopt(curl, CURLOPT_POST, TRUE);\r
- curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postMessage.c_str());\r
- curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, -1);\r
- \r
- // the url to get\r
- std::string search_url = "http://www.freesound.org/searchTextXML.php";\r
- curl_easy_setopt(curl, CURLOPT_URL, search_url.c_str());\r
-\r
- // perform the online search \r
- connection = 1;\r
- CURLcode res = curl_easy_perform(curl);\r
- if( res != 0 ) {\r
- toLog("curl login error\n");\r
- toLog(curl_easy_strerror(res));\r
- connection = 0;\r
- }\r
- \r
- result = xml_page.memory;\r
- toLog( result.c_str() );\r
-\r
- // free the memory\r
- if(xml_page.memory){\r
- free( xml_page.memory );\r
- xml_page.memory = NULL;\r
- xml_page.size = 0;\r
- }\r
+ curl_easy_setopt(curl, CURLOPT_URL, url.c_str() );\r
+ std::cerr << "doRequest: " << url << std::endl;\r
+ \r
+ // perform online request\r
+ CURLcode res = curl_easy_perform(curl);\r
+ if( res != 0 ) {\r
+ std::cerr << "curl error " << res << " (" << curl_easy_strerror(res) << ")" << std::endl;\r
+ return "";\r
+ }\r
\r
- }\r
+ // free the memory\r
+ if (xml_page.memory) {\r
+ result = xml_page.memory;\r
}\r
+ \r
+ free (xml_page.memory);\r
+ xml_page.memory = NULL;\r
+ xml_page.size = 0;\r
\r
return result;\r
}\r
\r
-//------------------------------------------------------------------------\r
-std::string Mootcher::changeExtension(std::string filename)\r
-{\r
- std::string aiff = ".aiff";\r
- std::string aif = ".aif";\r
- std::string wav = ".wav";\r
- std::string mp3 = ".mp3";\r
- std::string ogg = ".ogg";\r
- std::string flac = ".flac";\r
-\r
- std::string replace = ".xml";\r
- int pos = 0;\r
-\r
- pos = (int)filename.find(aiff);\r
- if(pos != std::string::npos) filename.replace(pos, aiff.size(), replace); \r
- pos = (int)filename.find(aif);\r
- if(pos != std::string::npos) filename.replace(pos, aif.size(), replace); \r
- pos = (int)filename.find(wav);\r
- if(pos != std::string::npos) filename.replace(pos, wav.size(), replace); \r
- pos = (int)filename.find(mp3);\r
- if(pos != std::string::npos) filename.replace(pos, mp3.size(), replace); \r
- pos = (int)filename.find(ogg);\r
- if(pos != std::string::npos) filename.replace(pos, ogg.size(), replace); \r
- pos = (int)filename.find(flac);\r
- if(pos != std::string::npos) filename.replace(pos, flac.size(), replace); \r
-\r
- return filename;\r
-}\r
-//------------------------------------------------------------------------\r
-void Mootcher::GetXml(std::string ID, struct MemoryStruct &xml_page)\r
+\r
+std::string Mootcher::searchText(std::string query, int page, std::string filter, enum sortMethod sort)\r
{\r
+ std::string params = "";\r
+ char buf[24];\r
\r
- if(curl) {\r
- setcUrlOptions();\r
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); \r
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&xml_page);\r
-\r
- // URL to get\r
- std::string getxml_url = "http://www.freesound.org/samplesViewSingleXML.php?id=";\r
- getxml_url += ID;\r
-\r
- curl_easy_setopt(curl, CURLOPT_URL, getxml_url.c_str() );\r
- \r
- // get it!\r
- connection = 1;\r
- CURLcode res = curl_easy_perform(curl);\r
- if( res != 0 ) {\r
- toLog("curl login error\n");\r
- toLog(curl_easy_strerror(res));\r
- connection = 0;\r
- }\r
+ if (page > 1) {\r
+ snprintf(buf, 23, "p=%d&", page);\r
+ params += buf;\r
}\r
+ \r
+ params += "q=" + query; \r
+\r
+ if (filter != "")\r
+ params += "&f=" + filter;\r
+ \r
+ if (sort)\r
+ params += "&s=" + sortMethodString(sort);\r
+\r
+ params += "&fields=id,original_filename,duration,serve"; \r
+\r
+ return doRequest("/sounds/search", params);\r
}\r
+\r
//------------------------------------------------------------------------\r
-std::string Mootcher::getXmlFile(std::string ID, int &length)\r
+\r
+std::string Mootcher::getSoundResourceFile(std::string ID)\r
{\r
- struct MemoryStruct xml_page;\r
- xml_page.memory = NULL;\r
- xml_page.size = NULL;\r
\r
- std::string xmlFileName;\r
+ std::string originalSoundURI;\r
std::string audioFileName;\r
- std::string filename;\r
- \r
- if(connection != 0) {\r
- // download the xmlfile into xml_page\r
- GetXml(ID, xml_page);\r
-\r
- // if sample ID does not exist on the freesound website\r
- if(strcmp(xml_page.memory, "sample non existant") == 0){\r
- free( xml_page.memory );\r
- sprintf(message, "getXmlFile: sample with ID:%s does not exist!\n", ID.c_str() );\r
- toLog(message);\r
- return filename;\r
- } else {\r
- XMLTree doc;\r
- doc.read_buffer( xml_page.memory );\r
- XMLNode *freesound = doc.root();\r
- \r
- // if the page is not a valid xml document with a 'freesound' root\r
- if( freesound == NULL){\r
- sprintf(message, "getXmlFile: There is no valid root in the xml file");\r
- toLog(message);\r
- } else {\r
- XMLNode *sample = freesound->child("sample");\r
- XMLNode *name = NULL;\r
- XMLNode *filesize = NULL;\r
- if (sample) {\r
- name = sample->child("originalFilename");\r
- filesize = sample->child("filesize");\r
- }\r
- \r
- // get the file name and size from xml file\r
- if (sample && name && filesize) {\r
- \r
- audioFileName = name->child("text")->content();\r
- sprintf( message, "getXmlFile: %s needs to be downloaded\n", audioFileName.c_str() );\r
- toLog(message);\r
-\r
- length = atoi(filesize->child("text")->content().c_str());\r
-\r
- // create new filename with the ID number\r
- filename = basePath;\r
- filename += "snd/";\r
- filename += sample->property("id")->value();\r
- filename += "-";\r
- filename += audioFileName;\r
- // change the extention into .xml\r
- xmlFileName = changeExtension( filename );\r
-\r
- sprintf(message, "getXmlFile: saving XML: %s\n", xmlFileName.c_str() );\r
- toLog(message);\r
- \r
- // save the xml file to disk\r
- doc.write(xmlFileName.c_str());\r
-\r
- //store all the tags in the database\r
- XMLNode *tags = sample->child("tags");\r
- if (tags) {\r
- XMLNodeList children = tags->children();\r
- XMLNodeConstIterator niter;\r
- std::vector<std::string> strings;\r
- for (niter = children.begin(); niter != children.end(); ++niter) {\r
- XMLNode *node = *niter;\r
- if( strcmp( node->name().c_str(), "tag") == 0 ) {\r
- XMLNode *text = node->child("text");\r
- if (text) strings.push_back(text->content());\r
- }\r
- }\r
- ARDOUR::Library->set_tags (std::string("//")+filename, strings);\r
- ARDOUR::Library->save_changes ();\r
+ std::string xml;\r
+\r
+\r
+ std::cerr << "getSoundResourceFile(" << ID << ")" << std::endl;\r
+\r
+ // download the xmlfile into xml_page\r
+ xml = doRequest("/sounds/" + ID, "");\r
+\r
+ XMLTree doc;\r
+ doc.read_buffer( xml.c_str() );\r
+ XMLNode *freesound = doc.root();\r
+\r
+ // if the page is not a valid xml document with a 'freesound' root\r
+ if (freesound == NULL) {\r
+ std::cerr << "getSoundResourceFile: There is no valid root in the xml file" << std::endl;\r
+ return "";\r
+ }\r
+\r
+ if (strcmp(doc.root()->name().c_str(), "response") != 0) {\r
+ std::cerr << "getSoundResourceFile: root =" << doc.root()->name() << ", != response" << std::endl;\r
+ return "";\r
+ }\r
+\r
+ XMLNode *name = freesound->child("original_filename");\r
+\r
+ // get the file name and size from xml file\r
+ if (name) {\r
+\r
+ audioFileName = basePath + "snd/" + ID + "-" + name->child("text")->content();\r
+\r
+ //store all the tags in the database\r
+ XMLNode *tags = freesound->child("tags");\r
+ if (tags) {\r
+ XMLNodeList children = tags->children();\r
+ XMLNodeConstIterator niter;\r
+ std::vector<std::string> strings;\r
+ for (niter = children.begin(); niter != children.end(); ++niter) {\r
+ XMLNode *node = *niter;\r
+ if( strcmp( node->name().c_str(), "resource") == 0 ) {\r
+ XMLNode *text = node->child("text");\r
+ if (text) {\r
+ // std::cerr << "tag: " << text->content() << std::endl;\r
+ strings.push_back(text->content());\r
}\r
}\r
- \r
- // clear the memory\r
- if(xml_page.memory){\r
- free( xml_page.memory );\r
- xml_page.memory = NULL;\r
- xml_page.size = 0;\r
- }\r
- return audioFileName;\r
}\r
+ ARDOUR::Library->set_tags (std::string("//")+audioFileName, strings);\r
+ ARDOUR::Library->save_changes ();\r
}\r
}\r
- else {\r
- return audioFileName;\r
- }\r
\r
+ return audioFileName;\r
}\r
\r
int audioFileWrite(void *buffer, size_t size, size_t nmemb, void *file)\r
};\r
\r
//------------------------------------------------------------------------\r
-std::string Mootcher::getFile(std::string ID)\r
+std::string Mootcher::getAudioFile(std::string originalFileName, std::string ID, std::string audioURL, SoundFileBrowser *caller)\r
{\r
- CURLcode result_curl;\r
+ ensureWorkingDir();\r
+ std::string audioFileName = basePath + "snd/" + ID + "-" + originalFileName;\r
+\r
+ // check to see if audio file already exists\r
+ FILE *testFile = g_fopen(audioFileName.c_str(), "r");\r
+ if (testFile) { \r
+ fseek (testFile , 0 , SEEK_END);\r
+ if (ftell (testFile) > 256) {\r
+ std::cerr << "audio file " << audioFileName << " already exists" << std::endl;\r
+ fclose (testFile);\r
+ return audioFileName;\r
+ }\r
+ \r
+ // else file was small, probably an error, delete it and try again\r
+ fclose(testFile);\r
+ remove( audioFileName.c_str() ); \r
+ }\r
\r
- std::string audioFileName;\r
+ if (!curl) {\r
+ return "";\r
+ }\r
\r
- if(connection != 0)\r
- {\r
- int length;\r
- std::string name = getXmlFile(ID, length);\r
- if( name != "" ){\r
-\r
- // create new filename with the ID number\r
- audioFileName += basePath;\r
- audioFileName += "snd/";\r
- audioFileName += ID;\r
- audioFileName += "-"; \r
- audioFileName += name;\r
- \r
- //check to see if audio file already exists\r
- FILE *testFile = fopen(audioFileName.c_str(), "r");\r
- if (testFile) { //TODO: should also check length to see if file is complete\r
- fseek (testFile , 0 , SEEK_END);\r
- if (ftell (testFile) == length) {\r
- sprintf(message, "%s already exists\n", audioFileName.c_str() );\r
- toLog(message);\r
- fclose (testFile);\r
- return audioFileName;\r
- } else {\r
- remove( audioFileName.c_str() ); //file was not correct length, delete it and try again\r
- } \r
- }\r
- \r
-\r
- //now download the actual file\r
- if (curl) {\r
-\r
- FILE* theFile;\r
- theFile = fopen( audioFileName.c_str(), "wb" );\r
-\r
- // create the download url, this url will also update the download statics on the site\r
- std::string audioURL;\r
- audioURL += "http://www.freesound.org/samplesDownload.php?id=";\r
- audioURL += ID;\r
-\r
- setcUrlOptions();\r
- curl_easy_setopt(curl, CURLOPT_URL, audioURL.c_str() );\r
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, audioFileWrite);\r
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, theFile);\r
-\r
- connection = 1;\r
- CURLcode res = curl_easy_perform(curl);\r
- if( res != 0 ) {\r
- toLog("curl login error\n");\r
- toLog(curl_easy_strerror(res));\r
- connection = 0;\r
- }\r
+ //if already canceling a previous download, bail out here ( this can happen b/c getAudioFile gets called by various UI update funcs )\r
+ if ( caller->freesound_download_cancel ) {\r
+ return "";\r
+ }\r
+ \r
+ //now download the actual file\r
+ FILE* theFile;\r
+ theFile = g_fopen( audioFileName.c_str(), "wb" );\r
\r
- fclose(theFile);\r
- }\r
+ if (!theFile) {\r
+ return "";\r
+ }\r
\r
-/*\r
- bar.dlnowMoo = 0;\r
- bar.dltotalMoo = 0;\r
- curl_easy_setopt (curl, CURLOPT_NOPROGRESS, 0); // turn on the process bar thingy\r
- curl_easy_setopt (curl, CURLOPT_PROGRESSFUNCTION, progress_callback);\r
- curl_easy_setopt (curl, CURLOPT_PROGRESSDATA, &bar);\r
-*/ \r
- }\r
+ // create the download url\r
+ audioURL += "?api_key=" + api_key;\r
+\r
+ setcUrlOptions();\r
+ curl_easy_setopt(curl, CURLOPT_URL, audioURL.c_str() );\r
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, audioFileWrite);\r
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, theFile);\r
+\r
+ std::cerr << "downloading " << audioFileName << " from " << audioURL << "..." << std::endl;\r
+ /* hack to get rid of the barber-pole stripes */\r
+ caller->freesound_progress_bar.hide();\r
+ caller->freesound_progress_bar.show();\r
+\r
+ std::string prog;\r
+ prog = string_compose (_("%1: [Stop]->"), originalFileName);\r
+ caller->freesound_progress_bar.set_text(prog);\r
+\r
+ curl_easy_setopt (curl, CURLOPT_NOPROGRESS, 0); // turn on the progress bar\r
+ curl_easy_setopt (curl, CURLOPT_PROGRESSFUNCTION, progress_callback);\r
+ curl_easy_setopt (curl, CURLOPT_PROGRESSDATA, caller);\r
+\r
+ CURLcode res = curl_easy_perform(curl);\r
+ fclose(theFile);\r
+\r
+ curl_easy_setopt (curl, CURLOPT_NOPROGRESS, 1); // turn off the progress bar\r
+ caller->freesound_progress_bar.set_fraction(0.0);\r
+ caller->freesound_progress_bar.set_text("");\r
+ \r
+ if( res != 0 ) {\r
+ std::cerr << "curl error " << res << " (" << curl_easy_strerror(res) << ")" << std::endl;\r
+ remove( audioFileName.c_str() ); \r
+ return "";\r
+ } else {\r
+ std::cerr << "done!" << std::endl;\r
+ // now download the tags &c.\r
+ getSoundResourceFile(ID);\r
}\r
\r
return audioFileName;\r
}\r
\r
//---------\r
-int Mootcher::progress_callback(void *bar, double dltotal, double dlnow, double ultotal, double ulnow)\r
+int Mootcher::progress_callback(void *caller, double dltotal, double dlnow, double ultotal, double ulnow)\r
{\r
- struct dlprocess *lbar = (struct dlprocess *) bar;\r
- lbar->dltotalMoo = dltotal;\r
- lbar->dlnowMoo = dlnow;\r
+\r
+SoundFileBrowser *sfb = (SoundFileBrowser *) caller;\r
+ //XXX I hope it's OK to do GTK things in this callback. Otherwise\r
+ // I'll have to do stuff like in interthread_progress_window.\r
+ if (sfb->freesound_download_cancel) {\r
+ return -1;\r
+ }\r
+ \r
+ \r
+ sfb->freesound_progress_bar.set_fraction(dlnow/dltotal);\r
+ /* Make sure the progress widget gets updated */\r
+ while (Glib::MainContext::get_default()->iteration (false)) {\r
+ /* do nothing */\r
+ }\r
+ std::cerr << "progress: " << dlnow << " of " << dltotal << " \r";\r
return 0;\r
}\r
+\r