Skip to content

Instantly share code, notes, and snippets.

@jhihn
Created June 14, 2021 20:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jhihn/19a4f03eeae473f3083dcecb4e25ad59 to your computer and use it in GitHub Desktop.
Save jhihn/19a4f03eeae473f3083dcecb4e25ad59 to your computer and use it in GitHub Desktop.
Lambdas with Qt's QNetworkAccessManager
class RemoteCloud {
QNetworkAccessManger m_nam;
QString URL(QString url); // left as an exercise to the reader, this just maps a short name to a server/versioned endpoint
QNetworkReplay *get(const QString& url);
QNetworkReply *post(const QString& url, const QVariantMap& object);
public:
QNetworkReply *get(const QString& endpoint, std::function<void(QNetworkReply*)> lambda, bool sync=false);
QNetworkReply *post(const QString& endpoint,
std::function<void(QNetworkReply*, const QVariantMap&)> lambda,
bool sync=false);
};
QNetworkReply *RemoteCloud::get(const QString& endpoint, const QVariantMap& item) {
QString url = URL(endpoint);
if (item.size()) {
QStringList params;
for(const QString& key : item.keys()) {
params.append(key + "=" + item[key].toString());
}
QString queryParams = params.join("&");
url += "?" + queryParams;
}
QNetworkRequest request = QNetworkRequest(url);
QNetworkReply* reply = m_nam.get(request);
return reply;
}
QNetworkReply *RemoteCloud::post(const QString& endpoint, const QVariantMap& item) {
QNetworkRequest request = QNetworkRequest(URL(endpoint));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QNetworkReply* reply = m_nam.post(request, body);
return reply;
}
QNetworkReply *RemoteCloud::get(
const QVariantMap& params,
const QString& endpoint, std::function<void(QNetworkReply*)> lambda,
bool sync,
) {
QEventLoop loop;
QNetworkReply *reply = get(endpoint, params);
QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
QObject::connect(reply, &QNetworkReply::finished, reply, [=]{
lambda(reply);
reply->deleteLater();
});
if (sync)
loop.exec(); // wait for finished
return reply;
}
QNetworkReply* RemoteCloud::post(const QString& endpoint,
std::function<void(QNetworkReply*, const QVariantMap&)> lambda,
bool sync) {
QEventLoop loop;
QNetworkReply* reply = nullptr;
reply = post(URL(endpoint), object);
QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
QObject::connect(reply, &QNetworkReply::finished, reply, [=]{
lambda(reply, object);
reply->deleteLater();
});
if (sync)
loop.exec(); // wait for finished
return reply;
}
remoteCloud->get(
"users",
QVariantMap(),
[=] (QNetworkReply* reply){
if (reply->error() == QNetworkReply::NoError) {
/* save users: write reply->body() */
} else {
qDebug() << Q_FUNC_INFO << reply->request().url() << reply->request().attribute(QNetworkRequest::CustomVerbAttribute) << reply->errorString();
}
/ /will be deleted automatically
},
false // will return immediately
);
// sequential object upload
for (const QVariantMap& event: QList<QVariantMap> {...} ) {
remoteCloud->post(
"events",
event,
[=] (QNetworkReply* reply){
if (reply->error() == QNetworkReply::NoError) {
/* file upload complete */
} else {
qDebug() << Q_FUNC_INFO << reply->request().url() << reply->request().attribute(QNetworkRequest::CustomVerbAttribute) << reply->errorString();
}
}, //lambda
true // sync
); // post
} // for file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment