Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
73d82e9562 |
No files matched your search
@@ -29,9 +29,7 @@ public:
|
||||
return false;
|
||||
auto *clipboard = QGuiApplication::clipboard();
|
||||
clipboard->setText(m_text, QClipboard::Clipboard);
|
||||
const bool copied = clipboard->text (QClipboard::Clipboard) == m_text
|
||||
&& (!QGuiApplication::platformName().startsWith (QStringLiteral ("wayland"))
|
||||
|| clipboard->ownsClipboard());
|
||||
const bool copied = clipboard->text(QClipboard::Clipboard) == m_text && (!QGuiApplication::platformName().startsWith(QStringLiteral("wayland")) || clipboard->ownsClipboard());
|
||||
m_status->setText(copied ? QStringLiteral("Short URL copied to clipboard.")
|
||||
: QStringLiteral("Could not copy the short URL. Click OK to retry."));
|
||||
#ifndef QT_NO_DEBUG
|
||||
|
||||
+1
-2
@@ -19,8 +19,7 @@ inline QUrl parseText (const QString &text) {
|
||||
if (urlText.size() >= 2) {
|
||||
const QChar first = urlText.front();
|
||||
const QChar last = urlText.back();
|
||||
if ((first == '\'' && last == '\'') || (first == '"' && last == '"')
|
||||
|| (first == '<' && last == '>'))
|
||||
if ((first == '\'' && last == '\'') || (first == '"' && last == '"') || (first == '<' && last == '>'))
|
||||
urlText = urlText.mid(1, urlText.size() - 2).trimmed();
|
||||
}
|
||||
|
||||
|
||||
+6
-19
@@ -1,6 +1,6 @@
|
||||
#include "mainwindow.h"
|
||||
#include "clipboardurl.h"
|
||||
#include "clipboardresultdialog.h"
|
||||
#include "clipboardurl.h"
|
||||
#include "ui_mainwindow.h"
|
||||
#include "yourlsclient.h"
|
||||
|
||||
@@ -58,16 +58,7 @@ namespace {
|
||||
* @param parent Parent widget.
|
||||
*/
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow (parent)
|
||||
, ui (new Ui::MainWindow)
|
||||
, m_trayIcon (nullptr)
|
||||
, m_trayMenu (nullptr)
|
||||
, m_cutUrlAction (nullptr)
|
||||
, m_settingsAction (nullptr)
|
||||
, m_helpAction (nullptr)
|
||||
, m_aboutAction (nullptr)
|
||||
, m_exitAction (nullptr)
|
||||
, m_yourlsClient (new YourlsClient (this)) {
|
||||
: QMainWindow(parent), ui(new Ui::MainWindow), m_trayIcon(nullptr), m_trayMenu(nullptr), m_cutUrlAction(nullptr), m_settingsAction(nullptr), m_helpAction(nullptr), m_aboutAction(nullptr), m_exitAction(nullptr), m_yourlsClient(new YourlsClient(this)) {
|
||||
ui->setupUi(this);
|
||||
#ifndef QT_NO_DEBUG
|
||||
qDebug() << "[yourls-ui] debug build, executable:" << QCoreApplication::applicationFilePath()
|
||||
@@ -189,8 +180,7 @@ void MainWindow::showSettingsWindow() {
|
||||
* @brief Hides the settings window to tray when possible.
|
||||
*/
|
||||
void MainWindow::hideToTray() {
|
||||
if (!hasValidSettings() || m_trayIcon == nullptr
|
||||
|| !QSystemTrayIcon::isSystemTrayAvailable() || !m_trayIcon->isVisible()) {
|
||||
if (!hasValidSettings() || m_trayIcon == nullptr || !QSystemTrayIcon::isSystemTrayAvailable() || !m_trayIcon->isVisible()) {
|
||||
showSettingsWindow();
|
||||
return;
|
||||
}
|
||||
@@ -233,8 +223,7 @@ void MainWindow::cutUrlFromClipboard() {
|
||||
}
|
||||
|
||||
QUrl longUrl;
|
||||
if (QGuiApplication::platformName().startsWith (QStringLiteral ("wayland"))
|
||||
&& !isActiveWindow()) {
|
||||
if (QGuiApplication::platformName().startsWith(QStringLiteral("wayland")) && !isActiveWindow()) {
|
||||
// Wayland delivers clipboard offers to clients with keyboard focus.
|
||||
// A tray menu belongs to the shell and does not focus our application.
|
||||
QDialog clipboardDialog(this);
|
||||
@@ -260,8 +249,7 @@ void MainWindow::cutUrlFromClipboard() {
|
||||
if (!clipboardDialog.isActiveWindow())
|
||||
return;
|
||||
const auto *mimeData = QGuiApplication::clipboard()->mimeData();
|
||||
if ((mimeData != nullptr && !mimeData->formats().isEmpty())
|
||||
|| ++activePolls >= 20)
|
||||
if ((mimeData != nullptr && !mimeData->formats().isEmpty()) || ++activePolls >= 20)
|
||||
readClipboard();
|
||||
});
|
||||
#ifndef QT_NO_DEBUG
|
||||
@@ -377,8 +365,7 @@ void MainWindow::loadSettings() {
|
||||
* @return True when the application can work from the tray.
|
||||
*/
|
||||
bool MainWindow::hasValidSettings() const {
|
||||
return !ui->urlLineEdit->text().trimmed().isEmpty()
|
||||
&& !ui->apiKeyLineEdit->text().trimmed().isEmpty();
|
||||
return !ui->urlLineEdit->text().trimmed().isEmpty() && !ui->apiKeyLineEdit->text().trimmed().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,11 +25,9 @@ int main (int argc, char **argv) {
|
||||
check(ClipboardUrl::parseText(QString::fromUtf8(text)) == expected, text);
|
||||
}
|
||||
check(ClipboardUrl::parseText(QStringLiteral(
|
||||
"[Other label](https://git.himro.ca/explore/repos?filter=a%26b#section)"))
|
||||
== QUrl (QStringLiteral ("https://git.himro.ca/explore/repos?filter=a%26b#section")),
|
||||
"[Other label](https://git.himro.ca/explore/repos?filter=a%26b#section)")) == QUrl(QStringLiteral("https://git.himro.ca/explore/repos?filter=a%26b#section")),
|
||||
"Markdown must use the destination and preserve query and fragment");
|
||||
check (ClipboardUrl::parseText (QStringLiteral ("[Link](https://example.com/a_(b))"))
|
||||
== QUrl (QStringLiteral ("https://example.com/a_(b)")),
|
||||
check(ClipboardUrl::parseText(QStringLiteral("[Link](https://example.com/a_(b))")) == QUrl(QStringLiteral("https://example.com/a_(b)")),
|
||||
"Parentheses in URL paths must be preserved");
|
||||
for (const auto &text: {"", "not a URL", "https://", "[Link](https://)"})
|
||||
check(!ClipboardUrl::parseText(QString::fromUtf8(text)).isValid(), text);
|
||||
|
||||
@@ -40,18 +40,18 @@ private slots:
|
||||
QVERIFY(server.listen(QHostAddress::LocalHost));
|
||||
QByteArray requestData;
|
||||
const QByteArray body = QJsonDocument(QJsonObject{
|
||||
{"status", status}, {"code", code}, {"shorturl", shortUrl},
|
||||
{"url", QJsonObject {{"url", originalUrl}}}
|
||||
}).toJson (QJsonDocument::Compact);
|
||||
{"status", status},
|
||||
{"code", code},
|
||||
{"shorturl", shortUrl},
|
||||
{"url", QJsonObject{{"url", originalUrl}}}})
|
||||
.toJson(QJsonDocument::Compact);
|
||||
connect(&server, &QTcpServer::newConnection, this, [&]() {
|
||||
auto *socket = server.nextPendingConnection();
|
||||
connect(socket, &QTcpSocket::readyRead, &server, [&, socket]() {
|
||||
requestData += socket->readAll();
|
||||
if (!requestData.contains("\r\n\r\n"))
|
||||
return;
|
||||
socket->write ("HTTP/1.1 " + QByteArray::number (httpStatus)
|
||||
+ " Result\r\nContent-Type: application/json\r\nContent-Length: "
|
||||
+ QByteArray::number (body.size()) + "\r\nConnection: close\r\n\r\n" + body);
|
||||
socket->write("HTTP/1.1 " + QByteArray::number(httpStatus) + " Result\r\nContent-Type: application/json\r\nContent-Length: " + QByteArray::number(body.size()) + "\r\nConnection: close\r\n\r\n" + body);
|
||||
socket->disconnectFromHost();
|
||||
});
|
||||
});
|
||||
@@ -60,7 +60,8 @@ private slots:
|
||||
QSignalSpy failed(&client, &YourlsClient::shortenFailed);
|
||||
const QUrl source(QStringLiteral("https://git.himro.ca/explore/repos?q=a%26b&next=x+y#section"));
|
||||
client.shortenUrl({QStringLiteral("http://127.0.0.1:%1/api").arg(server.serverPort()),
|
||||
QStringLiteral ("test-signature")}, source);
|
||||
QStringLiteral("test-signature")},
|
||||
source);
|
||||
QTRY_COMPARE(succeeded.count() + failed.count(), 1);
|
||||
QCOMPARE(succeeded.count(), success ? 1 : 0);
|
||||
if (success)
|
||||
|
||||
+4
-13
@@ -15,8 +15,7 @@
|
||||
* @param parent QObject parent.
|
||||
*/
|
||||
YourlsClient::YourlsClient(QObject *parent)
|
||||
: QObject (parent)
|
||||
, m_networkAccessManager (new QNetworkAccessManager (this)) {
|
||||
: QObject(parent), m_networkAccessManager(new QNetworkAccessManager(this)) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,16 +81,9 @@ void YourlsClient::shortenUrl (const YourlsSettings &settings, const QUrl &longU
|
||||
const QJsonDocument jsonDocument = QJsonDocument::fromJson(body, &parseError);
|
||||
const QJsonObject object = jsonDocument.object();
|
||||
const QUrl existingShortUrl(object.value(QStringLiteral("shorturl")).toString());
|
||||
const QUrl existingLongUrl (object.value (QStringLiteral ("url")).toObject()
|
||||
.value (QStringLiteral ("url")).toString());
|
||||
const QUrl existingLongUrl(object.value(QStringLiteral("url")).toObject().value(QStringLiteral("url")).toString());
|
||||
// YOURLS reports duplicate URLs as HTTP 400, but returns the existing link.
|
||||
if (reply->attribute (QNetworkRequest::HttpStatusCodeAttribute).toInt() == 400
|
||||
&& object.value (QStringLiteral ("status")).toString() == QStringLiteral ("fail")
|
||||
&& object.value (QStringLiteral ("code")).toString() == QStringLiteral ("error:url")
|
||||
&& existingLongUrl == longUrl && existingShortUrl.isValid()
|
||||
&& (existingShortUrl.scheme() == QStringLiteral ("https")
|
||||
|| existingShortUrl.scheme() == QStringLiteral ("http"))
|
||||
&& !existingShortUrl.host().isEmpty()) {
|
||||
if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 400 && object.value(QStringLiteral("status")).toString() == QStringLiteral("fail") && object.value(QStringLiteral("code")).toString() == QStringLiteral("error:url") && existingLongUrl == longUrl && existingShortUrl.isValid() && (existingShortUrl.scheme() == QStringLiteral("https") || existingShortUrl.scheme() == QStringLiteral("http")) && !existingShortUrl.host().isEmpty()) {
|
||||
#ifndef QT_NO_DEBUG
|
||||
qDebug() << "[yourls] reusing existing short URL:" << existingShortUrl;
|
||||
#endif
|
||||
@@ -144,8 +136,7 @@ void YourlsClient::shortenUrl (const YourlsSettings &settings, const QUrl &longU
|
||||
}
|
||||
|
||||
const QUrl shortUrl(shortUrlText);
|
||||
if (!shortUrl.isValid() || shortUrl.host().isEmpty()
|
||||
|| (shortUrl.scheme() != QStringLiteral ("https") && shortUrl.scheme() != QStringLiteral ("http"))) {
|
||||
if (!shortUrl.isValid() || shortUrl.host().isEmpty() || (shortUrl.scheme() != QStringLiteral("https") && shortUrl.scheme() != QStringLiteral("http"))) {
|
||||
reply->deleteLater();
|
||||
emit shortenFailed(QStringLiteral("YOURLS returned an invalid short URL: %1").arg(shortUrlText));
|
||||
return;
|
||||
|
||||
Reference in new issue
Block a user