From: Shane Synan Date: Wed, 20 Jun 2018 09:05:00 +0000 (-0500) Subject: common: Make CommitDate Unix epoch, handle legacy X-Git-Tag: 0.13-rc1~25 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=fa56ee7fc1b94ea27da6b27c919d6df1c0e0490d;hp=cb63e88d483f74c8f2f6e06c35c9d18be45cebaa common: Make CommitDate Unix epoch, handle legacy Leave CommitDate (BuildDate) in Unix epoch format, converting it on demand when displayed. This allows clients to localize the time shown. Add tryFormatUnixEpoch, which checks a string for Unix epoch, parsing as date/time if possible, otherwise letting the string through. This avoids breaking protocol or any existing packaging scripts that set commit date to a string. Check for empty commit/build dates when using them, replacing with "Unknown date" or "unknown" as appropriate. Don't encode this in Quassel::setupBuildInfo() to allow for location-specific treatment and client-side translation. --- diff --git a/src/common/quassel.cpp b/src/common/quassel.cpp index 86ab48b7..67eac802 100644 --- a/src/common/quassel.cpp +++ b/src/common/quassel.cpp @@ -299,19 +299,13 @@ void Quassel::setupBuildInfo() // Check if we got a commit hash if (!QString(GIT_HEAD).isEmpty()) { buildInfo.commitHash = GIT_HEAD; - QDateTime date; -#if QT_VERSION >= 0x050800 - date.setSecsSinceEpoch(GIT_COMMIT_DATE); -#else - // toSecsSinceEpoch() was added in Qt 5.8. Manually downconvert to seconds for now. - // See https://doc.qt.io/qt-5/qdatetime.html#toMSecsSinceEpoch - // Warning generated if not converting the 1000 to a qint64 first. - date.setMSecsSinceEpoch(GIT_COMMIT_DATE * (qint64)1000); -#endif - buildInfo.commitDate = date.toString(); + // Set to Unix epoch, wrapped as a string for backwards-compatibility + buildInfo.commitDate = QString::number(GIT_COMMIT_DATE); } else if (!QString(DIST_HASH).contains("Format")) { buildInfo.commitHash = DIST_HASH; + // Leave as Unix epoch if set as Unix epoch, but don't force this for + // backwards-compatibility with existing packaging/release tools that might set strings. buildInfo.commitDate = QString(DIST_DATE); } diff --git a/src/common/util.cpp b/src/common/util.cpp index b42f4fbf..a2c4e25e 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -363,3 +363,29 @@ bool scopeMatch(const QString &string, const QString &scopeRule, const bool &isR return matches || (invertedRuleFound && !normalRuleFound); } } + + +QString tryFormatUnixEpoch(const QString &possibleEpochDate) +{ + // Does the string resemble a Unix epoch? Parse as 64-bit time + qint64 secsSinceEpoch = possibleEpochDate.toLongLong(); + if (secsSinceEpoch == 0) { + // Parsing either failed, or '0' was sent. No need to distinguish; either way, it's not + // useful as epoch. + // See https://doc.qt.io/qt-5/qstring.html#toLongLong + return possibleEpochDate; + } + + // Time checks out, parse it + QDateTime date; +#if QT_VERSION >= 0x050800 + date.setSecsSinceEpoch(secsSinceEpoch); +#else + // toSecsSinceEpoch() was added in Qt 5.8. Manually downconvert to seconds for now. + // See https://doc.qt.io/qt-5/qdatetime.html#toMSecsSinceEpoch + date.setMSecsSinceEpoch(secsSinceEpoch * 1000); +#endif + + // Return the localized date/time + return date.toString(); +} diff --git a/src/common/util.h b/src/common/util.h index 8b312f93..d72dd8ed 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -101,3 +101,14 @@ QString formatCurrentDateTimeInString(const QString &formatStr); */ bool scopeMatch(const QString &string, const QString &scopeRule, const bool &isRegEx = false, const bool &isCaseSensitive = false); + +/** + * Try to localize a given date/time in seconds from Unix epoch, pass through string if invalid + * + * Allows compatibility with date/time fields that may or may not be in Unix epoch format, + * localizing if possible, leaving alone if not. + * + * @param possibleEpochDate Date/time that might be in seconds since Unix epoch format + * @return Localized date/time if parse succeeded, otherwise the source string + */ +QString tryFormatUnixEpoch(const QString &possibleEpochDate); diff --git a/src/core/coresessioneventprocessor.cpp b/src/core/coresessioneventprocessor.cpp index eb2ec0e3..76cddb3f 100644 --- a/src/core/coresessioneventprocessor.cpp +++ b/src/core/coresessioneventprocessor.cpp @@ -1634,6 +1634,9 @@ void CoreSessionEventProcessor::handleCtcpTime(CtcpEvent *e) void CoreSessionEventProcessor::handleCtcpVersion(CtcpEvent *e) { - e->setReply(QString("Quassel IRC %1 (built on %2) -- https://www.quassel-irc.org") - .arg(Quassel::buildInfo().plainVersionString).arg(Quassel::buildInfo().commitDate)); + // Deliberately do not translate project name + e->setReply(QString("Quassel IRC %1 (version date %2) -- https://www.quassel-irc.org") + .arg(Quassel::buildInfo().plainVersionString) + .arg(Quassel::buildInfo().commitDate.isEmpty() ? + "unknown" : tryFormatUnixEpoch(Quassel::buildInfo().commitDate))); } diff --git a/src/qtui/aboutdlg.cpp b/src/qtui/aboutdlg.cpp index 2fc3d6ea..14684888 100644 --- a/src/qtui/aboutdlg.cpp +++ b/src/qtui/aboutdlg.cpp @@ -26,6 +26,7 @@ #include "aboutdata.h" #include "icon.h" #include "quassel.h" +#include "util.h" AboutDlg::AboutDlg(QWidget *parent) : QDialog(parent) @@ -36,10 +37,21 @@ AboutDlg::AboutDlg(QWidget *parent) ui.setupUi(this); ui.quasselLogo->setPixmap(QPixmap{":/pics/quassel-64.svg"}); // don't let the icon theme affect our logo here - ui.versionLabel->setText(QString(tr("Version: %1
Version date: %2
Protocol version: %3")) - .arg(Quassel::buildInfo().fancyVersionString) - .arg(Quassel::buildInfo().commitDate) - .arg(Quassel::buildInfo().protocolVersion)); + QString versionDate; + if (Quassel::buildInfo().commitDate.isEmpty()) { + // This shouldn't happen, but sometimes the packaging environment cannot set a proper + // date/time. Add a fallback just in case. + versionDate = QString("%1").arg(tr("Unknown date")); + } + else { + versionDate = tryFormatUnixEpoch(Quassel::buildInfo().commitDate); + } + ui.versionLabel->setText(QString(tr("Version: %1
" + "Version date: %2
" + "Protocol version: %3")) + .arg(Quassel::buildInfo().fancyVersionString) + .arg(versionDate) + .arg(Quassel::buildInfo().protocolVersion)); ui.aboutTextBrowser->setHtml(about()); ui.authorTextBrowser->setHtml(authors()); ui.contributorTextBrowser->setHtml(contributors()); diff --git a/src/qtui/coreinfodlg.cpp b/src/qtui/coreinfodlg.cpp index d9527358..b1759776 100644 --- a/src/qtui/coreinfodlg.cpp +++ b/src/qtui/coreinfodlg.cpp @@ -25,6 +25,7 @@ #include "bufferwidget.h" #include "client.h" #include "icon.h" +#include "util.h" CoreInfoDlg::CoreInfoDlg(QWidget *parent) : QDialog(parent) { ui.setupUi(this); @@ -94,7 +95,13 @@ void CoreInfoDlg::coreInfoChanged(const QVariantMap &coreInfo) { } else { ui.labelCoreVersion->setText(coreInfo["quasselVersion"].toString()); // "BuildDate" for compatibility - ui.labelCoreVersionDate->setText(coreInfo["quasselBuildDate"].toString()); + if (coreInfo["quasselBuildDate"].toString().isEmpty()) { + ui.labelCoreVersionDate->setText(QString("%1").arg(tr("Unknown date"))); + } + else { + ui.labelCoreVersionDate->setText( + tryFormatUnixEpoch(coreInfo["quasselBuildDate"].toString())); + } ui.labelClientCount->setNum(coreInfo["sessionConnectedClients"].toInt()); } diff --git a/src/qtui/coresessionwidget.cpp b/src/qtui/coresessionwidget.cpp index 97993f4f..fbbb39b8 100644 --- a/src/qtui/coresessionwidget.cpp +++ b/src/qtui/coresessionwidget.cpp @@ -22,6 +22,7 @@ #include "client.h" #include "coresessionwidget.h" +#include "util.h" CoreSessionWidget::CoreSessionWidget(QWidget *parent) @@ -36,7 +37,12 @@ void CoreSessionWidget::setData(QMap map) ui.sessionGroup->setTitle(map["remoteAddress"].toString()); ui.labelLocation->setText(map["location"].toString()); ui.labelClient->setText(map["clientVersion"].toString()); - ui.labelVersionDate->setText(map["clientVersionDate"].toString()); + if (map["clientVersionDate"].toString().isEmpty()) { + ui.labelVersionDate->setText(QString("%1").arg(tr("Unknown date"))); + } + else { + ui.labelVersionDate->setText(tryFormatUnixEpoch(map["clientVersionDate"].toString())); + } ui.labelUptime->setText(map["connectedSince"].toDateTime().toLocalTime().toString(Qt::DateFormat::SystemLocaleShortDate)); if (map["location"].toString().isEmpty()) { ui.labelLocation->hide(); diff --git a/version.h.in b/version.h.in index 59112c92..4be8e522 100644 --- a/version.h.in +++ b/version.h.in @@ -7,8 +7,10 @@ // Determined from Git #define GIT_HEAD "@GIT_HEAD@" #define GIT_DESCRIBE "@GIT_DESCRIBE@" +// Unix epoch in seconds #define GIT_COMMIT_DATE @GIT_COMMIT_DATE@ // Will be substituted in official tarballs #define DIST_HASH "$Format:%H$" +// Unix epoch in seconds #define DIST_DATE "$Format:%at$"