Initial commit. First draft v0.1
This commit is contained in:
108
yourlsclient.cpp
Normal file
108
yourlsclient.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
#include "yourlsclient.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QUrlQuery>
|
||||
|
||||
/**
|
||||
* @brief Constructs the client.
|
||||
* @param parent QObject parent.
|
||||
*/
|
||||
YourlsClient::YourlsClient (QObject *parent)
|
||||
: QObject (parent)
|
||||
, m_networkAccessManager (new QNetworkAccessManager (this)) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Requests a short URL from the YOURLS API.
|
||||
* @param settings API endpoint and signature.
|
||||
* @param longUrl Source URL to shorten.
|
||||
*/
|
||||
void YourlsClient::shortenUrl (const YourlsSettings &settings, const QUrl &longUrl) {
|
||||
if (settings.apiUrl.trimmed().isEmpty()) {
|
||||
emit shortenFailed (QStringLiteral ("API URL is empty."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (settings.signature.trimmed().isEmpty()) {
|
||||
emit shortenFailed (QStringLiteral ("API signature is empty."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!longUrl.isValid() || longUrl.scheme().isEmpty() || longUrl.host().isEmpty()) {
|
||||
emit shortenFailed (QStringLiteral ("Clipboard does not contain a valid URL."));
|
||||
return;
|
||||
}
|
||||
|
||||
QUrl requestUrl (settings.apiUrl);
|
||||
if (!requestUrl.isValid()) {
|
||||
emit shortenFailed (QStringLiteral ("Configured API URL is invalid: %1").arg (settings.apiUrl));
|
||||
return;
|
||||
}
|
||||
|
||||
QUrlQuery query;
|
||||
query.addQueryItem (QStringLiteral ("signature"), settings.signature);
|
||||
query.addQueryItem (QStringLiteral ("action"), QStringLiteral ("shorturl"));
|
||||
query.addQueryItem (QStringLiteral ("format"), QStringLiteral ("json"));
|
||||
query.addQueryItem (QStringLiteral ("url"), longUrl.toString (QUrl::FullyDecoded));
|
||||
requestUrl.setQuery (query);
|
||||
|
||||
QNetworkRequest request (requestUrl);
|
||||
request.setHeader (QNetworkRequest::UserAgentHeader, QStringLiteral ("yourls-ui/1.0"));
|
||||
|
||||
QNetworkReply *reply = m_networkAccessManager->get (request);
|
||||
|
||||
connect (reply, &QNetworkReply::finished, this, [this, reply]() {
|
||||
const QByteArray body = reply->readAll();
|
||||
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
const QString details = QStringLiteral ("Network error: %1\nHTTP status: %2\nResponse body:\n%3")
|
||||
.arg (reply->errorString(),
|
||||
reply->attribute (QNetworkRequest::HttpStatusCodeAttribute).toString(),
|
||||
QString::fromUtf8 (body));
|
||||
reply->deleteLater();
|
||||
emit shortenFailed (details);
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonParseError parseError;
|
||||
const QJsonDocument jsonDocument = QJsonDocument::fromJson (body, &parseError);
|
||||
if (parseError.error != QJsonParseError::NoError || !jsonDocument.isObject()) {
|
||||
const QString details = QStringLiteral ("Failed to parse YOURLS response as JSON: %1\nResponse body:\n%2")
|
||||
.arg (parseError.errorString(), QString::fromUtf8 (body));
|
||||
reply->deleteLater();
|
||||
emit shortenFailed (details);
|
||||
return;
|
||||
}
|
||||
|
||||
const QJsonObject object = jsonDocument.object();
|
||||
const QString status = object.value (QStringLiteral ("status")).toString();
|
||||
const QString shortUrlText = object.value (QStringLiteral ("shorturl")).toString();
|
||||
|
||||
if (status.compare (QStringLiteral ("success"), Qt::CaseInsensitive) != 0 || shortUrlText.isEmpty()) {
|
||||
QStringList details;
|
||||
details << QStringLiteral ("YOURLS returned an error.");
|
||||
if (object.contains (QStringLiteral ("message")))
|
||||
details << QStringLiteral ("Message: %1").arg (object.value (QStringLiteral ("message")).toString());
|
||||
if (object.contains (QStringLiteral ("code")))
|
||||
details << QStringLiteral ("Code: %1").arg (object.value (QStringLiteral ("code")).toVariant().toString());
|
||||
details << QStringLiteral ("Raw response:\n%1").arg (QString::fromUtf8 (body));
|
||||
reply->deleteLater();
|
||||
emit shortenFailed (details.join (QStringLiteral ("\n")));
|
||||
return;
|
||||
}
|
||||
|
||||
const QUrl shortUrl (shortUrlText);
|
||||
if (!shortUrl.isValid()) {
|
||||
reply->deleteLater();
|
||||
emit shortenFailed (QStringLiteral ("YOURLS returned an invalid short URL: %1").arg (shortUrlText));
|
||||
return;
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
emit shortenSucceeded (shortUrl);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user