debug fleche
This commit is contained in:
BIN
fleche.xcf
Normal file
BIN
fleche.xcf
Normal file
Binary file not shown.
2
main.cpp
2
main.cpp
@@ -61,7 +61,7 @@ int main(int argc, char *argv[])
|
|||||||
pws2mqtt = new Pws2mqtt;
|
pws2mqtt = new Pws2mqtt;
|
||||||
|
|
||||||
pws2mqtt->listeningHttp();
|
pws2mqtt->listeningHttp();
|
||||||
notify (QString("Program started").toUtf8(), "default");
|
notify (QString("Program started"), "default");
|
||||||
|
|
||||||
a.exec();
|
a.exec();
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE QtCreatorProject>
|
<!DOCTYPE QtCreatorProject>
|
||||||
<!-- Written by QtCreator 9.0.1, 2025-10-05T23:00:49. -->
|
<!-- Written by QtCreator 9.0.1, 2025-10-12T11:32:20. -->
|
||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>EnvironmentId</variable>
|
<variable>EnvironmentId</variable>
|
||||||
@@ -81,6 +81,9 @@
|
|||||||
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
|
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
|
||||||
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
|
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
|
||||||
</valuemap>
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="CppEditor.QuickFix">
|
||||||
|
<value type="bool" key="UseGlobalSettings">true</value>
|
||||||
|
</valuemap>
|
||||||
</valuemap>
|
</valuemap>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
@@ -94,7 +97,7 @@
|
|||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||||
<value type="int" key="EnableQmlDebugging">0</value>
|
<value type="int" key="EnableQmlDebugging">1</value>
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/daniel/develop/pws2mqtt-qt/build/debug</value>
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/daniel/develop/pws2mqtt-qt/build/debug</value>
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/daniel/develop/pws2mqtt-qt/build/debug</value>
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/daniel/develop/pws2mqtt-qt/build/debug</value>
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
@@ -139,6 +142,7 @@
|
|||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
|
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
|
||||||
|
<value type="int" key="QtQuickCompiler">1</value>
|
||||||
</valuemap>
|
</valuemap>
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/daniel/develop/pws2mqtt-qt/build/Release</value>
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/daniel/develop/pws2mqtt-qt/build/Release</value>
|
||||||
|
|||||||
117
pws2mqtt.cpp
117
pws2mqtt.cpp
@@ -13,6 +13,8 @@
|
|||||||
#include <QtMath>
|
#include <QtMath>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QTransform>
|
#include <QTransform>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
extern MqttClient *mqttClient;
|
extern MqttClient *mqttClient;
|
||||||
extern Pws2mqtt *pws2mqtt;
|
extern Pws2mqtt *pws2mqtt;
|
||||||
@@ -38,6 +40,7 @@ static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *use
|
|||||||
}
|
}
|
||||||
|
|
||||||
QMap <QByteArray, QVariant> propertyList;
|
QMap <QByteArray, QVariant> propertyList;
|
||||||
|
QMap <QByteArray, double> propertiesValue;
|
||||||
QMap <QByteArray, QPair<QString, QByteArray>> propertyName
|
QMap <QByteArray, QPair<QString, QByteArray>> propertyName
|
||||||
{
|
{
|
||||||
{"tempf", {"Température extérieure", "°C"}},
|
{"tempf", {"Température extérieure", "°C"}},
|
||||||
@@ -191,12 +194,13 @@ void Pws2mqtt::parseData(QList<std::pair<QString, QString>> queryList)
|
|||||||
propertyValue = round(fahrenheitToCelsius(fValue));
|
propertyValue = round(fahrenheitToCelsius(fValue));
|
||||||
debug (DEBUGMACRO, "timeTemp = " + timeTemp.time().toString() + " - current :" + QDateTime::currentDateTime().toString() , DEBUG);
|
debug (DEBUGMACRO, "timeTemp = " + timeTemp.time().toString() + " - current :" + QDateTime::currentDateTime().toString() , DEBUG);
|
||||||
|
|
||||||
if (compare (propertyList[name].toDouble(), propertyValue, 1) and timeTemp < QDateTime::currentDateTime())
|
if (compare (propertiesValue[name], propertyValue, 1) and timeTemp < QDateTime::currentDateTime())
|
||||||
{
|
{
|
||||||
//notif += formatNotifString (propertyName[name].first, propertyName[name].second, QByteArray::number(qPow(propertyValue, 1.0)));
|
//notif += formatNotifString (propertyName[name].first, propertyName[name].second, QByteArray::number(qPow(propertyValue, 1.0)));
|
||||||
//debug (DEBUGMACRO, "", DEBUG);
|
//debug (DEBUGMACRO, "", DEBUG);
|
||||||
timeTemp = timeTemp.currentDateTime().addSecs(300);
|
timeTemp = timeTemp.currentDateTime().addSecs(300);
|
||||||
propertyList[name] = propertyValue;
|
propertyList[name] = propertyValue;
|
||||||
|
propertiesValue[name] = propertyValue;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
/*}else if (name == "indoortempf")
|
/*}else if (name == "indoortempf")
|
||||||
@@ -215,10 +219,11 @@ void Pws2mqtt::parseData(QList<std::pair<QString, QString>> queryList)
|
|||||||
propertyValue = value.toFloat();
|
propertyValue = value.toFloat();
|
||||||
debug (DEBUGMACRO, name + " : " + QByteArray::number(propertyValue), DEBUG);
|
debug (DEBUGMACRO, name + " : " + QByteArray::number(propertyValue), DEBUG);
|
||||||
|
|
||||||
if (compare (propertyList[name].toFloat(), propertyValue, 3))
|
if (compare (propertiesValue[name], propertyValue, 3))
|
||||||
{
|
{
|
||||||
//notif += formatNotifString (propertyName[name].first, propertyName[name].second , value);
|
//notif += formatNotifString (propertyName[name].first, propertyName[name].second , value);
|
||||||
propertyList[name] = propertyValue;
|
propertyList[name] = propertyValue;
|
||||||
|
propertiesValue[name] = propertyValue;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}else if (name == "windchillf")
|
}else if (name == "windchillf")
|
||||||
@@ -226,12 +231,13 @@ void Pws2mqtt::parseData(QList<std::pair<QString, QString>> queryList)
|
|||||||
static QDateTime timeWindchill = QDateTime::currentDateTime().addSecs(-600);
|
static QDateTime timeWindchill = QDateTime::currentDateTime().addSecs(-600);
|
||||||
propertyValue = round(fahrenheitToCelsius(value.toFloat()));
|
propertyValue = round(fahrenheitToCelsius(value.toFloat()));
|
||||||
debug (DEBUGMACRO, name + " : " + QByteArray::number(propertyValue), DEBUG);
|
debug (DEBUGMACRO, name + " : " + QByteArray::number(propertyValue), DEBUG);
|
||||||
if (compare (propertyList[name].toFloat(), propertyValue, 1) and timeWindchill < QDateTime::currentDateTime())
|
if (compare (propertiesValue[name], propertyValue, 1) and timeWindchill < QDateTime::currentDateTime())
|
||||||
{
|
{
|
||||||
//notif += formatNotifString (propertyName[name].first, propertyName[name].second , QByteArray::number(qPow(propertyValue, 1.0)));
|
//notif += formatNotifString (propertyName[name].first, propertyName[name].second , QByteArray::number(qPow(propertyValue, 1.0)));
|
||||||
//debug (DEBUGMACRO, "Notif = #" + notif + "#", DEBUG);
|
//debug (DEBUGMACRO, "Notif = #" + notif + "#", DEBUG);
|
||||||
timeWindchill = timeWindchill.currentDateTime().addSecs(300);
|
timeWindchill = timeWindchill.currentDateTime().addSecs(300);
|
||||||
propertyList[name] = propertyValue;
|
propertyList[name] = propertyValue;
|
||||||
|
propertiesValue[name] = propertyValue;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}else if (name == "winddir")
|
}else if (name == "winddir")
|
||||||
@@ -313,13 +319,34 @@ void Pws2mqtt::parseData(QList<std::pair<QString, QString>> queryList)
|
|||||||
ecart = 0.01;
|
ecart = 0.01;
|
||||||
}
|
}
|
||||||
debug (DEBUGMACRO, name + " : " + QByteArray::number(propertyValue), DEBUG);
|
debug (DEBUGMACRO, name + " : " + QByteArray::number(propertyValue), DEBUG);
|
||||||
if (compare (propertyList[name].toFloat(), propertyValue, ecart))
|
if (compare (propertiesValue[name], propertyValue, ecart))
|
||||||
{
|
{
|
||||||
//notif += formatNotifString (propertyName[name].first, propertyName[name].second , value);
|
//notif += formatNotifString (propertyName[name].first, propertyName[name].second , value);
|
||||||
QString pluviosite = getPluviosite(propertyValue);
|
QString pluviosite = getPluviosite(propertyValue);
|
||||||
priority = setPriority (priority, 4);
|
priority = setPriority (priority, 4);
|
||||||
//debug (DEBUGMACRO, "Notif = #" + notif + "#", DEBUG);
|
//debug (DEBUGMACRO, "Notif = #" + notif + "#", DEBUG);
|
||||||
propertyList[name] = pluviosite + " : " + QString::number(round(propertyValue*100)/100);
|
propertyList[name] = pluviosite + " : " + QString::number(round(propertyValue*100)/100);
|
||||||
|
propertiesValue[name] = propertyValue;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}else if (name == "dailyrainin")
|
||||||
|
{
|
||||||
|
static double ecart;
|
||||||
|
propertyValue = pair.second.toFloat();
|
||||||
|
if (propertyValue == 0)
|
||||||
|
{
|
||||||
|
ecart = 0.0001;
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
ecart = 0.01;
|
||||||
|
}
|
||||||
|
debug (DEBUGMACRO, name + " : " + QByteArray::number(propertyValue), DEBUG);
|
||||||
|
if (compare (propertiesValue[name], propertyValue, ecart))
|
||||||
|
{
|
||||||
|
priority = setPriority (priority, 3);
|
||||||
|
//debug (DEBUGMACRO, "Notif = #" + notif + "#", DEBUG);
|
||||||
|
propertyList[name] = propertyValue;
|
||||||
|
propertiesValue[name] = propertyValue;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}else if (name == "baromin")
|
}else if (name == "baromin")
|
||||||
@@ -328,11 +355,12 @@ void Pws2mqtt::parseData(QList<std::pair<QString, QString>> queryList)
|
|||||||
|
|
||||||
propertyValue = tohPa(pair.second.toFloat());
|
propertyValue = tohPa(pair.second.toFloat());
|
||||||
debug (DEBUGMACRO, "Barometre en hPa : " + QByteArray::number(propertyValue), DEBUG);
|
debug (DEBUGMACRO, "Barometre en hPa : " + QByteArray::number(propertyValue), DEBUG);
|
||||||
if (compare (propertyList[name].toFloat(), propertyValue, 0.5))
|
if (compare (propertiesValue[name], propertyValue, 0.5))
|
||||||
{
|
{
|
||||||
//notif += formatNotifString (propertyName[name].first, propertyName[name].second , QByteArray::number(propertyValue));
|
//notif += formatNotifString (propertyName[name].first, propertyName[name].second , QByteArray::number(propertyValue));
|
||||||
//debug (DEBUGMACRO, "Notif = #" + notif + "#", DEBUG);
|
//debug (DEBUGMACRO, "Notif = #" + notif + "#", DEBUG);
|
||||||
propertyList[name] = propertyValue;
|
propertyList[name] = propertyValue;
|
||||||
|
propertiesValue[name] = propertyValue;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,7 +386,7 @@ void Pws2mqtt::parseData(QList<std::pair<QString, QString>> queryList)
|
|||||||
propertyValue = pair.second.toFloat();
|
propertyValue = pair.second.toFloat();
|
||||||
|
|
||||||
debug (DEBUGMACRO, name + " : " + QByteArray::number(propertyValue), DEBUG);
|
debug (DEBUGMACRO, name + " : " + QByteArray::number(propertyValue), DEBUG);
|
||||||
if (compare (propertyList[name].toFloat(), propertyValue, 1) and timeUV < QDateTime::currentDateTime())
|
if (compare (propertiesValue[name], propertyValue, 1) and timeUV < QDateTime::currentDateTime())
|
||||||
{
|
{
|
||||||
//notif += formatNotifString (propertyName[name].first, propertyName[name].second , value);
|
//notif += formatNotifString (propertyName[name].first, propertyName[name].second , value);
|
||||||
if (propertyValue == 5 )
|
if (propertyValue == 5 )
|
||||||
@@ -367,6 +395,7 @@ void Pws2mqtt::parseData(QList<std::pair<QString, QString>> queryList)
|
|||||||
priority = setPriority (priority, 4);
|
priority = setPriority (priority, 4);
|
||||||
timeUV = timeUV.currentDateTime().addSecs(300);
|
timeUV = timeUV.currentDateTime().addSecs(300);
|
||||||
propertyList[name] = propertyValue;
|
propertyList[name] = propertyValue;
|
||||||
|
propertiesValue[name] = propertyValue;
|
||||||
debug (DEBUGMACRO, "Notif = #" + notif + "#", DEBUG);
|
debug (DEBUGMACRO, "Notif = #" + notif + "#", DEBUG);
|
||||||
}
|
}
|
||||||
}/*else if (name == "lowbat")
|
}/*else if (name == "lowbat")
|
||||||
@@ -414,7 +443,7 @@ void Pws2mqtt::parseData(QList<std::pair<QString, QString>> queryList)
|
|||||||
if (dataType == "double")
|
if (dataType == "double")
|
||||||
{
|
{
|
||||||
debug(DEBUGMACRO, "datatype is 'double'", DEBUG);
|
debug(DEBUGMACRO, "datatype is 'double'", DEBUG);
|
||||||
valueBA = QByteArray::number(value.toFloat());
|
valueBA = QByteArray::number(round(value.toFloat()*100)/100);
|
||||||
}else if (dataType == "QString")
|
}else if (dataType == "QString")
|
||||||
{
|
{
|
||||||
debug(DEBUGMACRO, "datatype is 'QString'" + value.toString(), DEBUG);
|
debug(DEBUGMACRO, "datatype is 'QString'" + value.toString(), DEBUG);
|
||||||
@@ -594,6 +623,12 @@ QString formatNotifString (QString name, QString unit ,QByteArray value)
|
|||||||
return text += " \n";
|
return text += " \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t ReadFile(void *ptr, size_t size, size_t nmemb, void *stream) {
|
||||||
|
FILE *f = (FILE *)stream;
|
||||||
|
size_t n = fread(ptr, size, nmemb, f);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
void notify(QString notif, QString priority, QString inputPath)
|
void notify(QString notif, QString priority, QString inputPath)
|
||||||
{
|
{
|
||||||
CURL *curl;
|
CURL *curl;
|
||||||
@@ -616,7 +651,7 @@ void notify(QString notif, QString priority, QString inputPath)
|
|||||||
headers = curl_slist_append(headers, "Config: /etc/ntfy.client.yml");
|
headers = curl_slist_append(headers, "Config: /etc/ntfy.client.yml");
|
||||||
headers = curl_slist_append(headers, "Firebase: no");
|
headers = curl_slist_append(headers, "Firebase: no");
|
||||||
|
|
||||||
curl_mime *mime;
|
/*curl_mime *mime;
|
||||||
curl_mimepart *part;
|
curl_mimepart *part;
|
||||||
|
|
||||||
// Initialise la structure mime
|
// Initialise la structure mime
|
||||||
@@ -626,13 +661,7 @@ void notify(QString notif, QString priority, QString inputPath)
|
|||||||
part = curl_mime_addpart(mime);
|
part = curl_mime_addpart(mime);
|
||||||
curl_mime_name(part, "message");
|
curl_mime_name(part, "message");
|
||||||
curl_mime_data(part, notif.toUtf8().constData(), CURL_ZERO_TERMINATED);
|
curl_mime_data(part, notif.toUtf8().constData(), CURL_ZERO_TERMINATED);
|
||||||
|
*/
|
||||||
// Ajoute le fichier en pièce jointe
|
|
||||||
part = curl_mime_addpart(mime);
|
|
||||||
curl_mime_name(part, "attach");
|
|
||||||
curl_mime_filedata(part, inputPath.toStdString().c_str());
|
|
||||||
curl_mime_filename(part, QFileInfo(inputPath).fileName().toStdString().c_str());
|
|
||||||
|
|
||||||
// Configure la requête POST
|
// Configure la requête POST
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:81/Meteo");
|
curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:81/Meteo");
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
||||||
@@ -653,12 +682,68 @@ void notify(QString notif, QString priority, QString inputPath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Nettoie les ressources
|
// Nettoie les ressources
|
||||||
curl_mime_free(mime);
|
//curl_mime_free(mime);
|
||||||
curl_slist_free_all(headers);
|
curl_slist_free_all(headers);
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
}
|
}
|
||||||
// Nettoie libcurl
|
// Nettoie libcurl
|
||||||
curl_global_cleanup();
|
curl_global_cleanup();
|
||||||
|
|
||||||
|
if (!inputPath.isEmpty())
|
||||||
|
{
|
||||||
|
FILE *fd = fopen(inputPath.toStdString().c_str(), "rb");
|
||||||
|
|
||||||
|
if (!fd) {
|
||||||
|
perror("Erreur lors de l'ouverture du fichier");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Initialise libcurl
|
||||||
|
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||||
|
curl = curl_easy_init();
|
||||||
|
if (curl)
|
||||||
|
{
|
||||||
|
// Définis les en-têtes pour le titre et les priorités
|
||||||
|
struct curl_slist *headers = NULL;
|
||||||
|
headers = curl_slist_append(headers, "Title: Météo");
|
||||||
|
headers = curl_slist_append(headers, priority.toStdString().c_str());
|
||||||
|
headers = curl_slist_append(headers, "Config: /etc/ntfy.client.yml");
|
||||||
|
headers = curl_slist_append(headers, "Firebase: no");
|
||||||
|
headers = curl_slist_append(headers, "Content-Type: image/png");
|
||||||
|
headers = curl_slist_append(headers, "X-Original-Size: true");
|
||||||
|
headers = curl_slist_append(headers, "X-Filename: fleche.png");
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); // Configurer l'URL
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, "localhost:81/Meteo");
|
||||||
|
|
||||||
|
// Utiliser la méthode PUT (comme `curl -T`)
|
||||||
|
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||||
|
|
||||||
|
// Lire le fichier et l'envoyer en tant que body
|
||||||
|
curl_easy_setopt(curl, CURLOPT_READFUNCTION, ReadFile);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_READDATA, fd);
|
||||||
|
|
||||||
|
// Définir la taille du fichier (optionnel mais recommandé)
|
||||||
|
struct stat file_info;
|
||||||
|
fstat(fileno(fd), &file_info);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size);
|
||||||
|
|
||||||
|
// Exécuter la requête
|
||||||
|
res = curl_easy_perform(curl);
|
||||||
|
// Vérifie les erreurs
|
||||||
|
if (res != CURLE_OK)
|
||||||
|
{
|
||||||
|
debug(DEBUGMACRO, "Erreur libcurl :" + QString(curl_easy_strerror(res)), DEBUG);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
debug(DEBUGMACRO, "Notification envoyée avec succès", DEBUG);
|
||||||
|
}
|
||||||
|
// Nettoyer
|
||||||
|
fclose(fd);
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
}
|
||||||
|
// Nettoie libcurl
|
||||||
|
curl_global_cleanup();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rotateAndSaveImage(const QString &inputPath, const QString &outputPath, qreal angle)
|
void rotateAndSaveImage(const QString &inputPath, const QString &outputPath, qreal angle)
|
||||||
|
|||||||
Reference in New Issue
Block a user