get multiple data from json with QT C++ - c++

I need to get a multiple data from json, the first part I can read, but the json inside I can't get it.
So my data from API:
My code in c++/QT it's the next:
QString JsonFunctions::getUnits(QString token_type, QString access_token)
{
QString lista;
QEventLoop eventLoop;
QNetworkAccessManager mgr;
QObject::connect(&mgr, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
QJsonObject json;
QNetworkRequest request(QUrl("https://MYURL/api/v2/units"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
//request.setRawHeader("Content-Type", "application/json");
request.setRawHeader("Accept", "application/json");
QString sing = token_type + " " + access_token;
request.setRawHeader("Authorization", sing.toUtf8());
QSslConfiguration conf = request.sslConfiguration();
conf.setPeerVerifyMode(QSslSocket::VerifyNone);
request.setSslConfiguration(conf);
QNetworkReply *reply = mgr.get(request);
eventLoop.exec();
QString strReply = (QString)reply->readAll();
qDebug() << "reply" << strReply;
qDebug() << "code" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QJsonDocument jsonResponse = QJsonDocument::fromJson(strReply.toUtf8());
QJsonArray jsonArray = jsonResponse.array();
QJsonObject jsonObject = jsonResponse.object();
QVariantMap mainmap = jsonObject.toVariantMap();
QVariantList phraseList = mainmap["data"].toList();
QJsonObject jsonobjs = QJsonObject::fromVariantMap(mainmap);
QJsonArray dataObject = jsonobjs.value("data").toArray();
for(int i = 0; i < dataObject.count(); i++){
QJsonObject temp = dataObject[i].toObject();
units unitsTemp;
unitsTemp.id = temp.value("ac_role_name").toString();
unitsTemp.description = temp.value("description").toString();
unitsTemp.thing_name = temp.value("thing_name").toString();
unitsTemp.serial_number = temp.value("serial_number").toString();
unitsTemp.access_key = temp.value("access_key").toString();
unitsTemp.state = temp.value("state").toInt();
unitsTemp.location_id = temp.value("location_id").toString();
unitsTemp.billing_id = temp.value("billing_id").toString();
unitsTemp.created_at = temp.value("created_at").toString();
unitsTemp.update_at = temp.value("update_at").toString();
unitsTemp.nickname = temp.value("nickname").toString();
unitsTemp.image = temp.value("image").toString();
unitsTemp.status = temp.value("status").toString();
unitsTemp.ac_role_name = temp.value("ac_role_name").toString();
//QJsonValue siteValue = temp.value("location").toArray();
//QJsonObject locationObject = siteValue.toObject();
//How to get location data ?
QJsonArray dataObjectz = temp.value("location").toArray().at(0).toArray();
//unitsTemp.locations.address = locationObject.value("address").toString();
//devo prendere le location
QString debug;
}
return lista;
}
I've tried code and codes...but how to get location data ?? I don't found the solution works for me.
Any idea ?
I'm new in qt and c++. thanks.

The solutions it's:
QJsonObject locationObject = temp["location"].toObject();
QString addressFromLocation = locationObject.value("address").toString();
work for me

Related

C++ QHttpMultiPart

I have to send the image through the REST API service from my test C++ QT client to get some information about it.
I've been trying to figure out for very long time, what's wrong with my POST request according follow documentation...
link: https://docs.facecloud.tevian.ru/
So i do it next way using QHttpMultiPart and QNetworkReply
QUrl testUrl("https://backend.facecloud.tevian.ru/api/v1/photos");
QNetworkRequest request(testUrl);
//auth token i've got before
request.setRawHeader(QByteArray("Authorization"), token.toUtf8());
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart firstPart;
const QString header = "application/json";
firstPart.setHeader(QNetworkRequest::ContentTypeHeader, header);
QJsonObject req;
QJsonDocument doc;
QByteArray data;
req.insert("fd_min_size",0);
req.insert("fd_max_size",0);
req.insert("fd_threshold",0.8);
req.insert("rotate_until_faces_found",true);
req.insert("orientation_classifier",true);
QJsonArray array;
array.push_back("0");
array.push_back("0");
array.push_back("1000");
array.push_back("1000");
req.insert("face", array);
req.insert("person_id",1);
doc = QJsonDocument(req);
data = doc.toJson();
firstPart.setBody(data);
QString img_path = "C:/Users/brode/Downloads/hi.jpg";
QString img_name = "hi.jpg";
QHttpPart secondPart;
secondPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));
secondPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"preview_file\"; filename=\""+ img_name+ "\""));
QFile *file = new QFile(img_path);
if (!file->exists()) {
return;
}
file->open(QIODevice::ReadOnly);
secondPart.setBodyDevice(file);
file->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart
multiPart->append(firstPart);
multiPart->append(secondPart);
QNetworkReply* reply = manager.post(request, multiPart);
multiPart->setParent(reply); // delete the multiPart with the reply
connect(reply, &QNetworkReply::readyRead,this, &rest_handler::readyRead);
First time i faced REST API...What i've done wrong?
After playing around with the api you are using, You are using wrong request format, the endpoint expects request with Content-Type: image/jpeg not using multipart. Also values like fd_min_size, face... should be sent as query parameters not in request body. The following piece of code works fine:
double fd_min_size = 0;
double fd_max_size = 0;
double fd_threshold=0.8;
bool rotate_until_faces_found = false;
bool orientation_classifier = false;
QVector <int>face = {0, 0, 1000, 1000};
int person_id = 1;
QString path = "https://backend.facecloud.tevian.ru/api/v1/photos";
// You don't have to add them all.
path += "?fd_min_size=" + QString::number(fd_min_size);
path += "&fd_max_size=" + QString::number(fd_max_size);
path += "&fd_threshold=" + QString::number(fd_threshold);
path += "&rotate_until_faces_found=" + (rotate_until_faces_found ? QString("true") : QString("false"));
path += "&orientation_classifier=" + (orientation_classifier ? QString("true") : QString("false"));
path += "&face=";
for(int i = 0;i < static_cast<int>(face.size());i++) {
path += QString::number(face[i]);
if(i + 1 != static_cast<int>(face.size())) {
path += ",";
}
}
path += "&person_id=" + QString::number(person_id); // The only one required
QUrl testUrl(path);
QNetworkRequest request(testUrl);
//auth token i've got before
request.setRawHeader(QByteArray("Authorization"), "Bearer " + token.toUtf8());
request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));
QString img_path = "C:/Users/xxx/Pictures/face.jpg";
QFile *file = new QFile(img_path);
if (!file->exists() || !file->open(QIODevice::ReadOnly)) {
return;
}
auto manager = new QNetworkAccessManager();
QNetworkReply *reply = manager->post(request, file);

Qt Json Parsing c++

I am trying to parse json object in QT from an api. However when i try the codes written below i cannot parse the object. I simply want to get the information stored in those parameters.
API is
{
"error": {
"errorcode": 0,
"errorstring": ""
},
"login": 1,
"logintoken": "209b06aa7f059673db393ff7a731af1847344903b9733f026cc3a6f7a5b797b3"
}
The Codes are
QUrl ava_url("http://pinundpin.de/wsdemo/atgdemoapi_v3/index.php");
QNetworkRequest ava_request(ava_url);
ava_request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
QNetworkAccessManager *manager = new QNetworkAccessManager();
QEventLoop loop;
QObject::connect(manager,
SIGNAL(finished(QNetworkReply *)),
&loop,
SLOT(quit()));
QByteArray postData;
Username = "testwebser";
Passwd = "2017#QWEasdZXC";
postData.append("action=login&");
postData.append("password="+Passwd+"&");
postData.append("username="+Username);
QNetworkReply* reply = manager->post(ava_request,postData);
loop.exec();
QString response = (QString)reply->readAll();
qDebug()<< response;
QJsonDocument temp = QJsonDocument::fromJson(response.toUtf8());
QJsonObject jsonObj = temp.object();
qDebug() <<"error"<< jsonObj["error"].toString();
qDebug() <<"login"<< jsonObj["login"].toString();
qDebug() << "logintoken"<<jsonObj["logintoken"].toString();
the response string looks
and the output is
D/libAndroisShop.so(21944): ../AndroisShop/networkconnection.cpp:45 (QString NetworkConnection::Connect(QString, QString)): "<br><br>NO OF ROWDATA: 1{\"error\":{\"errorcode\":0,\"errorstring\":\"\"},\"login\":1,\"logintoken\":\"4daaf6b3dd5a26a2ad2c436e564bfa4d6c439ce4d0d6cd66705a8bdadddddaa0\"}"
D/libAndroisShop.so(21944): ../AndroisShop/networkconnection.cpp:50 (QString NetworkConnection::Connect(QString, QString)): error ""
D/libAndroisShop.so(21944): ../AndroisShop/networkconnection.cpp:51 (QString NetworkConnection::Connect(QString, QString)): login ""
D/libAndroisShop.so(21944): ../AndroisShop/networkconnection.cpp:52 (QString NetworkConnection::Connect(QString, QString)): logintoken ""
Postman Image
If you review the result of POSTMAN in raw mode you get the following:
What QNAM gets but POSTMAN has another algorithm to extract the json:
So a possible solution is to remove the unwanted element: <br><br>NO OF ROWDATA: 1, for this it takes advantage that the json must start with "{" so the superior substring is used.
QUrl ava_url("http://pinundpin.de/wsdemo/atgdemoapi_v3/index.php");
QNetworkRequest ava_request(ava_url);
ava_request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
QNetworkAccessManager *manager = new QNetworkAccessManager();
QEventLoop loop;
QObject::connect(manager,
&QNetworkAccessManager::finished,
&loop,
&QEventLoop::quit);
QByteArray postData;
QString Username = "testwebser";
QString Passwd = "2017#QWEasdZXC";
postData.append("action=login&");
postData.append("password="+Passwd+"&");
postData.append("username="+Username);
QNetworkReply *reply = manager->post(ava_request,postData);
loop.exec();
QByteArray response = reply->readAll();
QByteArray json = response.mid(response.indexOf("{"));
QJsonDocument temp = QJsonDocument::fromJson(json);
QJsonObject jsonObj = temp.object();
QJsonObject errorObj = jsonObj["error"].toObject();
qDebug()<<"error: "
<<"errorcode: "<< errorObj["errorcode"].toInt()
<<"errorstring: "<< errorObj["errorstring"].toString();
qDebug() <<"login"<< jsonObj["login"].toInt();
qDebug() << "logintoken"<<jsonObj["logintoken"].toString();
Output:
error: errorcode: 0 errorstring: ""
login 1
logintoken "cc7e46f34e0a268cecbaaeaad41b0ae2727cc7196b632574a4db16544576d012"

Error during multipart upload using Qt

I am trying to upload a file using QNetworkAccessManager, but I always get an error (Error transferring url - server replied: Bad Request). Below is my code
QString name = "Simple.txt";
QString type = "text/plain; charset=utf-8";
QString uploadUrl = "myuploadUrl";
// setup the multipart request
QString bound="---------------------------723690991551375881941828858";
QByteArray data(QString("--"+bound+"\r\n").toLatin1());
// write the file using standard method for multipart file upload
data += "Content-Disposition: form-data; name=\"file\"; filename=\""+name.toLatin1()+"\"\r\n";
data += "Content-Type: "+type.toLatin1()+"\r\n\r\n";
data += "Hello, I am simple file";
data += "\r\n";
data += "--" + bound;
qDebug() << data;
// make the request with appropriate headers
QNetworkRequest request(QUrl(uploadUrl));
request.setRawHeader(QByteArray("Content-Type"),QString("multipart/form-data; boundary=" + bound).toLatin1());
request.setRawHeader(QByteArray("Content-Length"), QString::number(data.length()).toLatin1());
QNetworkReply *reply = networkManager->post(request,data);
QObject::connect(reply, &QNetworkReply::finished, this, FileUploader::requestFinished);
However running this python script, which should do the same thing, works.
import requests
import json
file_name = "Simple.txt"
uploadUrl = "myUploadUrl";
resp = requests.post(uploadUrl, data=r["data"], files={"file": open(file_name, "rb")})
print (resp);
The problem was fixed by adding a data += "\r\n" at the end of the data.
Instead of creating request manually use QT internals. Here You can try this code which is working for me.
void OfflineLogHandler::uploadOfflineLogFile(QString filePath){
QUrl targateUlr(APIUrls::getInstance()->getFlightLogUploadURL()); //pass URL here
APIUrls *apiUrls = APIUrls::getInstance();
qDebug()<<"Target upload offline log url:"<<targateUlr;
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart formHeader;
formHeader.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"\"; filename=\""+filePath.section("/",-1)+"\""));
if(filePath.contains(".json"))
formHeader.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
else if(filePath.contains(".csv"))
formHeader.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/csv"));
QFile *file = new QFile(filePath);
file->open(QIODevice::ReadOnly);
formHeader.setBodyDevice(file);
multiPart->append(formHeader);
file->setParent(multiPart);
QNetworkRequest request;
request.setUrl(targateUlr);
QString CredData = apiUrls->getCredentials();
QString headerData = apiUrls->getApiAuthorizationType() + CredData;
qDebug()<<"access:"<<headerData.toLocal8Bit();
request.setRawHeader( "Authorization", headerData.toLocal8Bit() );
request.setRawHeader("CustomeData1","Data1");
request.setRawHeader("CustomeData2","Data2");
request.setHeader(QNetworkRequest::ContentTypeHeader,QString("multipart/form-data; boundary="+multiPart->boundary()).toLatin1());
QNetworkAccessManager *restclient; //in class
restclient = new QNetworkAccessManager(); //constructor
disconnect(restclient,SIGNAL(finished(QNetworkReply*)), this, nullptr);
connect(restclient, SIGNAL(finished(QNetworkReply*)), this, SLOT(handleFileUploadResponse(QNetworkReply*)));
networkReply = restclient->post(request,multiPart);
connect(networkReply,SIGNAL(uploadProgress(qint64, qint64)),this,SLOT(fileUprogress(qint64, qint64)));
qDebug()<<"net:"<<networkReply;
}

Why can't I parse the Cryptsy JSON API with Qt5/C++?

I'm trying to parse this JSON Web-API using Qt5 and C++ using QJsonDocument and QJsonObject as seen here. But I fail to access the JSON value of the QJsonObject.
This is what I've tried so far:
// Contains the whole API as QString...
QString data = QString(reply->readAll());
// Reads the JSON as QJsonDocument...
QJsonDocument jsonResponse = QJsonDocument::fromJson(data.toUtf8());
// Reads the JSON as QJsonObject...
QJsonObject jsonObject = jsonResponse.object();
Now I have my object well prepared, but trying to access the values of the JSON somehow fails:
// This returns an empty string ""!?!
qDebug() << jsonObject.value("success").toString();
Well, maybe I got the keys wrong:
// Let's check the keys...
QStringList stringList = jsonObject.keys();
for (QStringList::Iterator it = stringList.begin(); it != stringList.end(); ++it)
{
// This returns "success" and "return" - huh!?!
qDebug() << *it;
}
OK, the keys are veryfied, why is it not working?
// Let's check the values by using the keys directly...
for (QStringList::Iterator it = stringList.begin(); it != stringList.end(); ++it)
{
// This returns empty strings "" and "" - now what?!?
qDebug() << jsonObject.value(*it).toString();
}
This again, makes no sense at all. I can't see why I can not access the value of the JSON object by the keys. Any idea?
I tried exactly the same code on other JSON APIs (for example this one) without any issues. I am totally stuck here.
Here's my solution for Qt5 Json parsing the Cryptsy API.
QEventLoop loopEvent;
QNetworkAccessManager namMNGR;
QObject::connect(&namMNGR, SIGNAL(finished(QNetworkReply*)), &loopEvent, SLOT(quit()));
QNetworkRequest req(QUrl(QString("http://pubapi.cryptsy.com/api.php?method=singlemarketdata&marketid=%1").arg(marketID)));
QNetworkReply *reply = namMNGR.get(req);
loopEvent.exec();
//Json API parsing begins.
QString jsonSTR = reply->readAll();
if (!(reply->error() == QNetworkReply::NoError)) {
delete reply; //API Connection Problem.
}
QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonSTR.toUtf8());
QJsonObject obj1 = jsonDocument.object();
QJsonValue val1 = obj1.value(obj1.keys().first());
QJsonObject obj2 = val1.toObject();
QJsonValue val2 = obj2.value(obj2.keys().first());
QJsonObject obj3 = val2.toObject();
QJsonValue marketDataValue = obj3.value(obj3.keys().first());
QJsonObject marketDataObject = marketDataValue.toObject();
QJsonArray sellordersArray = marketDataObject["sellorders"].toArray();
Have you managed to get Authenticated POST API data from Qt5? I'm trying to figure out how to do it.

on uploading file to google-drive by using c++/qt filename of newfile is always untitled

I found a similar question: Google Drive API insert new file with Untitled name
but code is not attached there.
My code:
void googled::newuploadSettings(QNetworkReply *reply){
QByteArray data = reply->readAll();
qDebug() << data;
QString x = getValue(data,"access_token");
qDebug() << x;
x = "Bearer " + x;
qDebug() << x;
QNetworkRequest request;
//QString contentType = "text/plain";
QUrl url("https://www.googleapis.com/upload/drive/v2/files?uploadType=media");
//url.addQueryItem("originalFilename","sp");
request.setUrl(url);
request.setRawHeader("Content-Length","200000000");
request.setRawHeader("Content-Type","image/jpeg");
request.setRawHeader("title","sp");
//request.setRawHeader("X-Upload-Content-Length","20000000");
//request.setRawHeader("X-Upload-Content-Type","image/jpeg");
request.setRawHeader("Authorization",x.toLatin1());
//request.setRawHeader("Host","https://www.googleapis.com");
qDebug() << getValue(data,"access_token").toUtf8();
//request.setRawHeader()
QFile file("/home/saurabh/Pictures/005.jpg");
//file.setFileName("kashmir");
file.open(QIODevice::ReadOnly);
QByteArray arr = file.readAll();
file.close();
qDebug() << "file";
QString str = "a";
str.append(arr);
qDebug() << str;
m_netM = new QNetworkAccessManager;
QObject::connect(m_netM, SIGNAL(finished(QNetworkReply *)),
this, SLOT(uploadfinishedSlot(QNetworkReply *)));
m_netM->post(request,arr);
}
I know I have to set title field for giving name to file but am not able to figure out how I would do it in qt
title option should go to request body according to Files.insert() documentation
For instance, if header has
Content-Type: application/json
request body would be
{
"title": "sp"
}
To set title of the file to be "sp". Please look for qt documentation to find how to set request body.