update FluNetwork

This commit is contained in:
zhuzichu 2023-11-24 15:35:40 +08:00
parent 2f3ed2bd0f
commit 78f5dd0a61
6 changed files with 591 additions and 38 deletions

View File

@ -23,6 +23,10 @@ FluContentPage{
(status,errorString,result)=>{ (status,errorString,result)=>{
console.debug(status+";"+errorString+";"+result) console.debug(status+";"+errorString+";"+result)
} }
onCache:
(result)=>{
text_info.text = result
}
onSuccess: onSuccess:
(result)=>{ (result)=>{
text_info.text = result text_info.text = result
@ -51,21 +55,8 @@ FluContentPage{
implicitHeight: 36 implicitHeight: 36
text: "Get" text: "Get"
onClicked: { onClicked: {
text_info.text = ""
FluNetwork.get("https://httpbingo.org/get") FluNetwork.get("https://httpbingo.org/get")
.setTimeOut(10000)//15000
.setRetry(2)//3
.addQuery("name","孙悟空")
.addQuery("age",500)
.addQuery("address","花果山水帘洞")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Head"
onClicked: {
FluNetwork.head("https://httpbingo.org/head")
.addQuery("name","孙悟空") .addQuery("name","孙悟空")
.addQuery("age",500) .addQuery("age",500)
.addQuery("address","花果山水帘洞") .addQuery("address","花果山水帘洞")
@ -77,16 +68,31 @@ FluContentPage{
implicitHeight: 36 implicitHeight: 36
text: "Post Body" text: "Post Body"
onClicked: { onClicked: {
text_info.text = ""
FluNetwork.postBody("https://httpbingo.org/post") FluNetwork.postBody("https://httpbingo.org/post")
.setBody("花果山水帘洞美猴王齐天大圣孙悟空") .setBody("花果山水帘洞美猴王齐天大圣孙悟空")
.go(callable) .go(callable)
} }
} }
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Post Form"
onClicked: {
text_info.text = ""
FluNetwork.postForm("https://httpbingo.org/post")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.go(callable)
}
}
FluButton{ FluButton{
implicitWidth: parent.width implicitWidth: parent.width
implicitHeight: 36 implicitHeight: 36
text: "Post JSON" text: "Post JSON"
onClicked: { onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post") FluNetwork.postJson("https://httpbingo.org/post")
.add("name","孙悟空") .add("name","孙悟空")
.add("age",500) .add("age",500)
@ -99,6 +105,7 @@ FluContentPage{
implicitHeight: 36 implicitHeight: 36
text: "Post JSON Array" text: "Post JSON Array"
onClicked: { onClicked: {
text_info.text = ""
FluNetwork.postJsonArray("https://httpbingo.org/post") FluNetwork.postJsonArray("https://httpbingo.org/post")
.add("name","孙悟空") .add("name","孙悟空")
.add("age",500) .add("age",500)
@ -109,16 +116,230 @@ FluContentPage{
FluButton{ FluButton{
implicitWidth: parent.width implicitWidth: parent.width
implicitHeight: 36 implicitHeight: 36
text: "Post Form" text: "Put Body"
onClicked: { onClicked: {
FluNetwork.postForm("https://httpbingo.org/post") text_info.text = ""
FluNetwork.putBody("https://httpbingo.org/put")
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Put Form"
onClicked: {
text_info.text = ""
FluNetwork.putForm("https://httpbingo.org/put")
.add("name","孙悟空") .add("name","孙悟空")
.add("age",500) .add("age",500)
.add("address","花果山水帘洞") .add("address","花果山水帘洞")
.go(callable) .go(callable)
} }
} }
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Put JSON"
onClicked: {
text_info.text = ""
FluNetwork.putJson("https://httpbingo.org/put")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Put JSON Array"
onClicked: {
text_info.text = ""
FluNetwork.putJsonArray("https://httpbingo.org/put")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Patch Body"
onClicked: {
text_info.text = ""
FluNetwork.patchBody("https://httpbingo.org/patch")
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Patch Form"
onClicked: {
text_info.text = ""
FluNetwork.patchForm("https://httpbingo.org/patch")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Patch JSON"
onClicked: {
text_info.text = ""
FluNetwork.patchJson("https://httpbingo.org/patch")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Patch JSON Array"
onClicked: {
text_info.text = ""
FluNetwork.patchJsonArray("https://httpbingo.org/patch")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Delete Body"
onClicked: {
text_info.text = ""
FluNetwork.deleteBody("https://httpbingo.org/delete")
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Delete Form"
onClicked: {
text_info.text = ""
FluNetwork.deleteForm("https://httpbingo.org/delete")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Delete JSON"
onClicked: {
text_info.text = ""
FluNetwork.deleteJson("https://httpbingo.org/delete")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Delete JSON Array"
onClicked: {
text_info.text = ""
FluNetwork.deleteJsonArray("https://httpbingo.org/delete")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Custom Header"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.addHeader("os","PC")
.addHeader("version","1.0.0")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "RequestFailedReadCache"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.setCacheMode(FluNetworkType.RequestFailedReadCache)
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.add("cacheMode","RequestFailedReadCache")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "IfNoneCacheRequest"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.setCacheMode(FluNetworkType.IfNoneCacheRequest)
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.add("cacheMode","IfNoneCacheRequest")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "FirstCacheThenRequest"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.setCacheMode(FluNetworkType.FirstCacheThenRequest)
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.add("cacheMode","FirstCacheThenRequest")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Timeout And Retry"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.setTimeout(5000)
.setRetry(3)
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.add("timeout","5000")
.add("retry","3")
.go(callable)
}
}
} }
} }

View File

@ -22,6 +22,10 @@ FluContentPage{
(status,errorString,result)=>{ (status,errorString,result)=>{
console.debug(status+";"+errorString+";"+result) console.debug(status+";"+errorString+";"+result)
} }
onCache:
(result)=>{
text_info.text = result
}
onSuccess: onSuccess:
(result)=>{ (result)=>{
text_info.text = result text_info.text = result
@ -38,6 +42,7 @@ FluContentPage{
bottom: parent.bottom bottom: parent.bottom
left: parent.left left: parent.left
} }
boundsBehavior: Flickable.StopAtBounds
ScrollBar.vertical: FluScrollBar {} ScrollBar.vertical: FluScrollBar {}
contentHeight:layout_column.height contentHeight:layout_column.height
Column{ Column{
@ -49,21 +54,8 @@ FluContentPage{
implicitHeight: 36 implicitHeight: 36
text: "Get" text: "Get"
onClicked: { onClicked: {
text_info.text = ""
FluNetwork.get("https://httpbingo.org/get") FluNetwork.get("https://httpbingo.org/get")
.setTimeOut(10000)//15000
.setRetry(2)//3
.addQuery("name","孙悟空")
.addQuery("age",500)
.addQuery("address","花果山水帘洞")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Head"
onClicked: {
FluNetwork.head("https://httpbingo.org/head")
.addQuery("name","孙悟空") .addQuery("name","孙悟空")
.addQuery("age",500) .addQuery("age",500)
.addQuery("address","花果山水帘洞") .addQuery("address","花果山水帘洞")
@ -75,16 +67,31 @@ FluContentPage{
implicitHeight: 36 implicitHeight: 36
text: "Post Body" text: "Post Body"
onClicked: { onClicked: {
text_info.text = ""
FluNetwork.postBody("https://httpbingo.org/post") FluNetwork.postBody("https://httpbingo.org/post")
.setBody("花果山水帘洞美猴王齐天大圣孙悟空") .setBody("花果山水帘洞美猴王齐天大圣孙悟空")
.go(callable) .go(callable)
} }
} }
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Post Form"
onClicked: {
text_info.text = ""
FluNetwork.postForm("https://httpbingo.org/post")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.go(callable)
}
}
FluButton{ FluButton{
implicitWidth: parent.width implicitWidth: parent.width
implicitHeight: 36 implicitHeight: 36
text: "Post JSON" text: "Post JSON"
onClicked: { onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post") FluNetwork.postJson("https://httpbingo.org/post")
.add("name","孙悟空") .add("name","孙悟空")
.add("age",500) .add("age",500)
@ -97,6 +104,7 @@ FluContentPage{
implicitHeight: 36 implicitHeight: 36
text: "Post JSON Array" text: "Post JSON Array"
onClicked: { onClicked: {
text_info.text = ""
FluNetwork.postJsonArray("https://httpbingo.org/post") FluNetwork.postJsonArray("https://httpbingo.org/post")
.add("name","孙悟空") .add("name","孙悟空")
.add("age",500) .add("age",500)
@ -107,16 +115,230 @@ FluContentPage{
FluButton{ FluButton{
implicitWidth: parent.width implicitWidth: parent.width
implicitHeight: 36 implicitHeight: 36
text: "Post Form" text: "Put Body"
onClicked: { onClicked: {
FluNetwork.postForm("https://httpbingo.org/post") text_info.text = ""
FluNetwork.putBody("https://httpbingo.org/put")
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Put Form"
onClicked: {
text_info.text = ""
FluNetwork.putForm("https://httpbingo.org/put")
.add("name","孙悟空") .add("name","孙悟空")
.add("age",500) .add("age",500)
.add("address","花果山水帘洞") .add("address","花果山水帘洞")
.go(callable) .go(callable)
} }
} }
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Put JSON"
onClicked: {
text_info.text = ""
FluNetwork.putJson("https://httpbingo.org/put")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Put JSON Array"
onClicked: {
text_info.text = ""
FluNetwork.putJsonArray("https://httpbingo.org/put")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Patch Body"
onClicked: {
text_info.text = ""
FluNetwork.patchBody("https://httpbingo.org/patch")
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Patch Form"
onClicked: {
text_info.text = ""
FluNetwork.patchForm("https://httpbingo.org/patch")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Patch JSON"
onClicked: {
text_info.text = ""
FluNetwork.patchJson("https://httpbingo.org/patch")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Patch JSON Array"
onClicked: {
text_info.text = ""
FluNetwork.patchJsonArray("https://httpbingo.org/patch")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Delete Body"
onClicked: {
text_info.text = ""
FluNetwork.deleteBody("https://httpbingo.org/delete")
.setBody("花果山水帘洞美猴王齐天大圣孙悟空")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Delete Form"
onClicked: {
text_info.text = ""
FluNetwork.deleteForm("https://httpbingo.org/delete")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Delete JSON"
onClicked: {
text_info.text = ""
FluNetwork.deleteJson("https://httpbingo.org/delete")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Delete JSON Array"
onClicked: {
text_info.text = ""
FluNetwork.deleteJsonArray("https://httpbingo.org/delete")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Custom Header"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.addHeader("os","PC")
.addHeader("version","1.0.0")
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "RequestFailedReadCache"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.setCacheMode(FluNetworkType.RequestFailedReadCache)
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.add("cacheMode","RequestFailedReadCache")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "IfNoneCacheRequest"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.setCacheMode(FluNetworkType.IfNoneCacheRequest)
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.add("cacheMode","IfNoneCacheRequest")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "FirstCacheThenRequest"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.setCacheMode(FluNetworkType.FirstCacheThenRequest)
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.add("cacheMode","FirstCacheThenRequest")
.go(callable)
}
}
FluButton{
implicitWidth: parent.width
implicitHeight: 36
text: "Timeout And Retry"
onClicked: {
text_info.text = ""
FluNetwork.postJson("https://httpbingo.org/post")
.setTimeout(5000)
.setRetry(3)
.add("name","孙悟空")
.add("age",500)
.add("address","花果山水帘洞")
.add("timeout","5000")
.add("retry","3")
.go(callable)
}
}
} }
} }

View File

@ -26,6 +26,18 @@ Q_ENUM_NS(CacheMode)
QML_NAMED_ELEMENT(FluHttpType) QML_NAMED_ELEMENT(FluHttpType)
} }
namespace FluNetworkType {
Q_NAMESPACE
enum CacheMode {
NoCache = 0x0000,
RequestFailedReadCache = 0x0001,
IfNoneCacheRequest = 0x0002,
FirstCacheThenRequest = 0x0004,
};
Q_ENUM_NS(CacheMode)
QML_NAMED_ELEMENT(FluNetworkType)
}
namespace FluScreenshotType { namespace FluScreenshotType {
Q_NAMESPACE Q_NAMESPACE
enum CaptrueMode { enum CaptrueMode {

View File

@ -6,7 +6,10 @@
#include <QJsonDocument> #include <QJsonDocument>
#include <QNetworkReply> #include <QNetworkReply>
#include <QJsonObject> #include <QJsonObject>
#include <QNetworkDiskCache>
#include <QJsonArray> #include <QJsonArray>
#include <QStandardPaths>
#include <QDir>
NetworkCallable::NetworkCallable(QObject *parent):QObject{parent}{ NetworkCallable::NetworkCallable(QObject *parent):QObject{parent}{
@ -64,6 +67,11 @@ NetworkParams* NetworkParams::add(QString key,QVariant val){
return this; return this;
} }
NetworkParams* NetworkParams::addFile(QString key,QVariant val){
_fileMap.insert(key,val);
return this;
}
NetworkParams* NetworkParams::addHeader(QString key,QVariant val){ NetworkParams* NetworkParams::addHeader(QString key,QVariant val){
_headerMap.insert(key,val); _headerMap.insert(key,val);
return this; return this;
@ -79,7 +87,7 @@ NetworkParams* NetworkParams::setBody(QString val){
return this; return this;
} }
NetworkParams* NetworkParams::setTimeOut(int val){ NetworkParams* NetworkParams::setTimeout(int val){
_timeout = val; _timeout = val;
return this; return this;
} }
@ -89,16 +97,47 @@ NetworkParams* NetworkParams::setRetry(int val){
return this; return this;
} }
NetworkParams* NetworkParams::setCacheMode(int val){
_cacheMode = val;
return this;
}
QString NetworkParams::buildCacheKey(){
QJsonObject obj;
obj.insert("url",_url);
obj.insert("method",method2String());
obj.insert("body",_body);
obj.insert("query",QString(QJsonDocument::fromVariant(_queryMap).toJson(QJsonDocument::Compact)));
obj.insert("param",QString(QJsonDocument::fromVariant(_paramMap).toJson(QJsonDocument::Compact)));
obj.insert("header",QString(QJsonDocument::fromVariant(_headerMap).toJson(QJsonDocument::Compact)));
QByteArray data = QJsonDocument(obj).toJson(QJsonDocument::Compact);
return QCryptographicHash::hash(data, QCryptographicHash::Sha256).toHex();
}
void NetworkParams::go(NetworkCallable* callable){ void NetworkParams::go(NetworkCallable* callable){
FluNetwork::getInstance()->handle(this,callable); FluNetwork::getInstance()->handle(this,callable);
} }
void FluNetwork::handle(NetworkParams* params,NetworkCallable* c){ void FluNetwork::handle(NetworkParams* params,NetworkCallable* c){
std::shared_ptr<int> times = std::make_shared<int>(0); QString cacheKey = params->buildCacheKey();
QPointer<NetworkCallable> callable(c); QPointer<NetworkCallable> callable(c);
if(!callable.isNull()){ if(!callable.isNull()){
callable->start(); callable->start();
} }
if(params->_cacheMode == FluNetworkType::CacheMode::FirstCacheThenRequest && cacheExists(cacheKey)){
if(!callable.isNull()){
callable->cache(readCache(cacheKey));
}
}
if(params->_cacheMode == FluNetworkType::CacheMode::IfNoneCacheRequest && cacheExists(cacheKey)){
if(!callable.isNull()){
callable->cache(readCache(cacheKey));
callable->finish();
params->deleteLater();
}
return;
}
std::shared_ptr<int> times = std::make_shared<int>(0);
QUrl url(params->_url); QUrl url(params->_url);
QNetworkAccessManager* manager = new QNetworkAccessManager(); QNetworkAccessManager* manager = new QNetworkAccessManager();
QNetworkReply *reply = nullptr; QNetworkReply *reply = nullptr;
@ -106,7 +145,7 @@ void FluNetwork::handle(NetworkParams* params,NetworkCallable* c){
addQueryParam(&url,params->_queryMap); addQueryParam(&url,params->_queryMap);
QNetworkRequest request(url); QNetworkRequest request(url);
addHeaders(&request,params->_headerMap); addHeaders(&request,params->_headerMap);
connect(manager,&QNetworkAccessManager::finished,this,[this,params,request,callable,manager,times](QNetworkReply *reply){ connect(manager,&QNetworkAccessManager::finished,this,[this,params,request,callable,manager,times,cacheKey](QNetworkReply *reply){
if(reply->error() != QNetworkReply::NoError && *times < params->getRetry()) { if(reply->error() != QNetworkReply::NoError && *times < params->getRetry()) {
(*times)++; (*times)++;
sendRequest(manager,request,params,reply); sendRequest(manager,request,params,reply);
@ -115,14 +154,23 @@ void FluNetwork::handle(NetworkParams* params,NetworkCallable* c){
QNetworkReply::NetworkError error = reply->error(); QNetworkReply::NetworkError error = reply->error();
if(error == QNetworkReply::NoError){ if(error == QNetworkReply::NoError){
if(!callable.isNull()){ if(!callable.isNull()){
if(params->_cacheMode != FluNetworkType::CacheMode::NoCache){
saveResponse(cacheKey,response);
}
callable->success(response); callable->success(response);
} }
}else{ }else{
if(!callable.isNull()){ if(!callable.isNull()){
int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if(params->_cacheMode == FluNetworkType::CacheMode::RequestFailedReadCache && cacheExists(cacheKey)){
if(!callable.isNull()){
callable->cache(readCache(cacheKey));
}
}
callable->error(httpStatus,reply->errorString(),response); callable->error(httpStatus,reply->errorString(),response);
} }
} }
params->deleteLater();
reply->deleteLater(); reply->deleteLater();
manager->deleteLater(); manager->deleteLater();
if(!callable.isNull()){ if(!callable.isNull()){
@ -133,6 +181,32 @@ void FluNetwork::handle(NetworkParams* params,NetworkCallable* c){
sendRequest(manager,request,params,reply); sendRequest(manager,request,params,reply);
} }
QString FluNetwork::readCache(const QString& key){
auto filePath = getCacheFilePath(key);
QString result;
QFile file(filePath);
if(!file.exists()){
return result;
}
if (file.open(QIODevice::ReadOnly)) {
QTextStream stream(&file);
result = QString(QByteArray::fromBase64(stream.readAll().toUtf8()));
}
return result;
}
bool FluNetwork::cacheExists(const QString& key){
return QFile(getCacheFilePath(key)).exists();
}
QString FluNetwork::getCacheFilePath(const QString& key){
QDir cacheDir(_cacheDir);
if(!cacheDir.exists()){
cacheDir.mkpath(_cacheDir);
}
return cacheDir.absoluteFilePath(key);
}
void FluNetwork::sendRequest(QNetworkAccessManager* manager,QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply){ void FluNetwork::sendRequest(QNetworkAccessManager* manager,QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply){
if(reply){ if(reply){
reply->deleteLater(); reply->deleteLater();
@ -189,6 +263,16 @@ void FluNetwork::sendRequest(QNetworkAccessManager* manager,QNetworkRequest requ
} }
} }
void FluNetwork::saveResponse(QString key,QString response){
QSharedPointer<QFile> file(new QFile(getCacheFilePath(key)));
QIODevice::OpenMode mode = QIODevice::WriteOnly|QIODevice::Truncate;
if (!file->open(mode))
{
return;
}
file->write(response.toUtf8().toBase64());
}
void FluNetwork::addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& headers){ void FluNetwork::addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& headers){
QMapIterator<QString, QVariant> iter(headers); QMapIterator<QString, QVariant> iter(headers);
while (iter.hasNext()) while (iter.hasNext())
@ -213,6 +297,7 @@ FluNetwork::FluNetwork(QObject *parent): QObject{parent}
{ {
timeout(15000); timeout(15000);
retry(3); retry(3);
cacheDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation).append(QDir::separator()).append("network"));
} }
NetworkParams* FluNetwork::get(const QString& url){ NetworkParams* FluNetwork::get(const QString& url){

View File

@ -6,6 +6,7 @@
#include <QFile> #include <QFile>
#include <QJsonValue> #include <QJsonValue>
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include "Def.h"
#include "stdafx.h" #include "stdafx.h"
#include "singleton.h" #include "singleton.h"
@ -19,6 +20,7 @@ public:
Q_SIGNAL void finish(); Q_SIGNAL void finish();
Q_SIGNAL void error(int status,QString errorString,QString result); Q_SIGNAL void error(int status,QString errorString,QString result);
Q_SIGNAL void success(QString result); Q_SIGNAL void success(QString result);
Q_SIGNAL void cache(QString result);
}; };
class NetworkParams : public QObject class NetworkParams : public QObject
@ -46,10 +48,13 @@ public:
Q_INVOKABLE NetworkParams* addQuery(QString key,QVariant val); Q_INVOKABLE NetworkParams* addQuery(QString key,QVariant val);
Q_INVOKABLE NetworkParams* addHeader(QString key,QVariant val); Q_INVOKABLE NetworkParams* addHeader(QString key,QVariant val);
Q_INVOKABLE NetworkParams* add(QString key,QVariant val); Q_INVOKABLE NetworkParams* add(QString key,QVariant val);
Q_INVOKABLE NetworkParams* addFile(QString key,QVariant val);
Q_INVOKABLE NetworkParams* setBody(QString val); Q_INVOKABLE NetworkParams* setBody(QString val);
Q_INVOKABLE NetworkParams* setTimeOut(int val); Q_INVOKABLE NetworkParams* setTimeout(int val);
Q_INVOKABLE NetworkParams* setRetry(int val); Q_INVOKABLE NetworkParams* setRetry(int val);
Q_INVOKABLE NetworkParams* setCacheMode(int val);
Q_INVOKABLE void go(NetworkCallable* result); Q_INVOKABLE void go(NetworkCallable* result);
QString buildCacheKey();
QString method2String(); QString method2String();
int getTimeout(); int getTimeout();
int getRetry(); int getRetry();
@ -61,8 +66,10 @@ public:
QMap<QString, QVariant> _queryMap; QMap<QString, QVariant> _queryMap;
QMap<QString, QVariant> _headerMap; QMap<QString, QVariant> _headerMap;
QMap<QString, QVariant> _paramMap; QMap<QString, QVariant> _paramMap;
QMap<QString, QVariant> _fileMap;
int _timeout = -1; int _timeout = -1;
int _retry = -1; int _retry = -1;
int _cacheMode = FluNetworkType::CacheMode::NoCache;
}; };
class FluNetwork : public QObject class FluNetwork : public QObject
@ -70,6 +77,7 @@ class FluNetwork : public QObject
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(int,timeout) Q_PROPERTY_AUTO(int,timeout)
Q_PROPERTY_AUTO(int,retry) Q_PROPERTY_AUTO(int,retry)
Q_PROPERTY_AUTO(QString,cacheDir)
QML_NAMED_ELEMENT(FluNetwork) QML_NAMED_ELEMENT(FluNetwork)
QML_SINGLETON QML_SINGLETON
private: private:
@ -100,6 +108,10 @@ private:
void sendRequest(QNetworkAccessManager* manager,QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply); void sendRequest(QNetworkAccessManager* manager,QNetworkRequest request,NetworkParams* params,QNetworkReply*& reply);
void addQueryParam(QUrl* url,const QMap<QString, QVariant>& params); void addQueryParam(QUrl* url,const QMap<QString, QVariant>& params);
void addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& headers); void addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& headers);
void saveResponse(QString key,QString response);
QString readCache(const QString& key);
bool cacheExists(const QString& key);
QString getCacheFilePath(const QString& key);
}; };
#endif // FLUNETWORK_H #endif // FLUNETWORK_H

View File

@ -172,6 +172,7 @@ void FluentUI::registerTypes(const char *uri){
qmlRegisterUncreatableMetaObject(FluTimelineType::staticMetaObject, uri,major,minor,"FluTimelineType", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(FluTimelineType::staticMetaObject, uri,major,minor,"FluTimelineType", "Access to enums & flags only");
qmlRegisterUncreatableMetaObject(FluScreenshotType::staticMetaObject, uri,major,minor,"FluScreenshotType", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(FluScreenshotType::staticMetaObject, uri,major,minor,"FluScreenshotType", "Access to enums & flags only");
qmlRegisterUncreatableMetaObject(FluViewModelType::staticMetaObject, uri,major,minor,"FluViewModelType", "Access to enums & flags only"); qmlRegisterUncreatableMetaObject(FluViewModelType::staticMetaObject, uri,major,minor,"FluViewModelType", "Access to enums & flags only");
qmlRegisterUncreatableMetaObject(FluNetworkType::staticMetaObject, uri,major,minor,"FluNetworkType", "Access to enums & flags only");
qmlRegisterModule(uri,major,minor); qmlRegisterModule(uri,major,minor);
} }