click Posted August 14, 2010 Report Share Posted August 14, 2010 This is a routine to retrieve the torrent list from the WebAPI using C++. It was thrown together with CSimpleSocket, Json++ and this base64 library. It is currently being used to poll for torrent updates and post them to our chat server. Any glaring errors would be appreciated (i couldn't make jsonxx cache that object?). Hope it helps someone else get started - i couldn't find any c++ libraries that already had this under control#define UT_UADDR "127.0.0.1"#define UT_UPORT 81#define UT_UUSER "admin"#define UT_UPASS "admin"struct Torrent { string Name; string Label; double Progress; /* Range 0...1000*/};typedef map<string, Torrent> VTMAP;// ######################################///<summary>/// Escapes some invalid HTTP characters.///</summary>void httpEscape(string& sString) { int iFind; for(; { iFind = sString.find("="); if (iFind == sString.npos) break; sString.replace(iFind, 1, "%3D"); }}///<summary>/// Performs an HTTP/1.1 GET on the specified sHostname:iPort sPath and blocks until/// it recieves a result.///</summary>string httpGet(char* sHostname, char* sPath, int iPort, char* sUserAndPass) { // Construct query string sQuery = format("GET %s HTTP/1.1\nHost: %s:%d", sPath, sHostname, iPort); if (sUserAndPass) { sQuery.append("\nAuthorization: Basic "); sQuery.append(base64_encode((const unsigned char*) sUserAndPass, strlen(sUserAndPass))); } sQuery.append("\n\n"); // Connect to address CActiveSocket* sock = new CActiveSocket(); sock->Initialize(); sock->SetBlocking(); sock->Open((const uint8 *) sHostname, iPort); if (!(sock->Send((const uint8 *) sQuery.c_str(), sQuery.length()))) { delete sock; return "Couldn't send the query!\n"; } // Wait for the returned token sock->Receive(16384); if (!(sock->GetData())) { delete sock; return "Couldn't read the replied data!\n"; } // Copy and return the response char *cBuff = new char[sock->GetBytesReceived() + 16]; sock->GetBytesReceived(); sock->GetData(); memcpy(cBuff, sock->GetData(), sock->GetBytesReceived()); string sResult; sResult.assign(cBuff); delete[] cBuff; delete sock; return sResult;}///<summary>/// Communicates with the uTorrent WebUI and returns a list of torrents/// TODO: When uTorrent 2.1 is released, we might have to use cookie authentication as well///</summary>bool retrieveTorrents(VTMAP& vtResult) { // Retrieve token.html string sResponse = httpGet(UT_UADDR, "/gui/token.html", UT_UPORT, UT_UUSER ":" UT_UPASS); // Parse response for token string sToken = ""; int iPos = sResponse.find("div id='token'"); if (iPos) { iPos = sResponse.find(">", iPos); if (iPos) { int iLast = sResponse.find("</div", iPos++); sToken.assign(sResponse.substr(iPos, iLast-iPos)); } } if (!(sToken.length())) { printf("Couldn't find a connection token in the response!\n"); return false; } httpEscape(sToken); // Retrieve torrent list as JSON string sAddress = "/gui/?list=1&token="; sAddress.append(sToken); sResponse = httpGet(UT_UADDR, (char*)sAddress.c_str(), UT_UPORT, UT_UUSER ":" UT_UPASS); // Isolate the JSON and load into JSON structure iPos = sResponse.find("{"); int iEnd = sResponse.find("}"); string sJSON; sJSON.assign(sResponse.substr(iPos, iEnd - iPos + 1)); istringstream iJSON(sJSON); jsonxx::Object o; if (!(o.parse(iJSON, o))) { printf("Failed to parse JSON!\n"); return false; } // Extract the individual torrents if (!(o.has<jsonxx::Array>("torrents"))) { printf("Malformed JSON response!\n"); return false; } vtResult.clear(); for (int i=0,e = o.get<jsonxx::Array>("torrents").size(); i < e; i++) { Torrent t; t.Name = o.get<jsonxx::Array>("torrents").get<jsonxx::Array>(i).get<string>(2); // Magic t.Label = o.get<jsonxx::Array>("torrents").get<jsonxx::Array>(i).get<string>(11); t.Progress = o.get<jsonxx::Array>("torrents").get<jsonxx::Array>(i).get<double>(4); vtResult[t.Name] = t; } // Tidy up return true;} Link to comment Share on other sites More sharing options...
tamaroth Posted August 23, 2010 Report Share Posted August 23, 2010 Hey,I was just starting my own project (automatic file extractor for freshly downloaded files) and i was wondering how should i communicate with utorrent, when i stumbled upon your code. After changing some code i made it work, so i wanted to thank you for this piece of code!Once i finish my project that it will be useable, i will post it on sourceforge so you can dl it and laugh at my puny c++ code ;p Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.