#5657 Make trial expiry notification live

This commit is contained in:
Andrew Nelless 2016-10-17 15:26:42 +01:00
parent e05ced287c
commit 714b2f6440
9 changed files with 154 additions and 42 deletions

View File

@ -55,7 +55,7 @@
<item> <item>
<widget class="QLabel" name="m_trialLabel"> <widget class="QLabel" name="m_trialLabel">
<property name="text"> <property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;6&lt;/span&gt; days of your Synergy Pro trial remain. &lt;a href=&quot;http://symless.com/pricing?src=gui&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Buy now!&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;%1&lt;/span&gt; days of your Synergy Pro trial remain. &lt;a href=&quot;http://symless.com/pricing?src=gui&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Buy now!&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="openExternalLinks"> <property name="openExternalLinks">
<bool>true</bool> <bool>true</bool>

View File

@ -39,7 +39,7 @@ ActivationDialog::~ActivationDialog()
void ActivationDialog::reject() void ActivationDialog::reject()
{ {
if (m_subscriptionManager->activeLicense() == kUnregistered) { if (m_subscriptionManager->activeEdition() == kUnregistered) {
CancelActivationDialog cancelActivationDialog(this); CancelActivationDialog cancelActivationDialog(this);
if (QDialog::Accepted == cancelActivationDialog.exec()) { if (QDialog::Accepted == cancelActivationDialog.exec()) {
m_subscriptionManager->skipActivation(); m_subscriptionManager->skipActivation();
@ -53,28 +53,35 @@ void ActivationDialog::reject()
void ActivationDialog::accept() void ActivationDialog::accept()
{ {
QMessageBox message; QMessageBox message;
QString error;
m_appConfig->activationHasRun(true); m_appConfig->activationHasRun(true);
m_appConfig->saveSettings(); m_appConfig->saveSettings();
std::pair<bool, QString> result;
try { try {
QString serialKey = ui->m_pTextEditSerialKey->toPlainText(); QString serialKey = ui->m_pTextEditSerialKey->toPlainText();
m_subscriptionManager->setSerialKey(serialKey); result = m_subscriptionManager->setSerialKey(serialKey);
} }
catch (std::exception& e) { catch (std::exception& e) {
message.critical(this, "Unknown Error", message.critical(this, "Unknown Error",
tr("An error occurred while trying to activate Synergy. " tr("An error occurred while trying to activate Synergy. "
"Please contact the helpdesk, and provide the " "Please contact the helpdesk, and provide the "
"following details.\n\n%1").arg(e.what())); "following information:\n\n%1").arg(e.what()));
refreshSerialKey(); refreshSerialKey();
return; return;
} }
if (m_subscriptionManager->activeLicense() != kUnregistered) { if (!result.first) {
message.critical(this, "Activation failed",
tr("%1").arg(result.second));
refreshSerialKey();
return;
}
if (m_subscriptionManager->activeEdition() != kUnregistered) {
message.information(this, "Activated!", message.information(this, "Activated!",
tr("Thanks for activating %1!").arg tr("Thanks for activating %1!").arg
(getEditionName(m_subscriptionManager->activeLicense()))); (m_subscriptionManager->activeEditionName()));
} }
QDialog::accept(); QDialog::accept();
} }

View File

@ -154,7 +154,7 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig,
connect (m_AppConfig, SIGNAL(sslToggled(bool)), connect (m_AppConfig, SIGNAL(sslToggled(bool)),
this, SLOT(sslToggled(bool)), Qt::QueuedConnection); this, SLOT(sslToggled(bool)), Qt::QueuedConnection);
m_SubscriptionManager->update(); m_SubscriptionManager->refresh();
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
@ -547,6 +547,10 @@ void MainWindow::startSynergy()
args << "--name" << getScreenName(); args << "--name" << getScreenName();
if (!appConfig().serialKey().isEmpty()) {
args << "--serial-key " << appConfig().serialKey();
}
if (desktopMode) if (desktopMode)
{ {
setSynergyProcess(new QProcess(this)); setSynergyProcess(new QProcess(this));
@ -1038,7 +1042,7 @@ void MainWindow::serverDetected(const QString name)
void MainWindow::setEdition(Edition edition) void MainWindow::setEdition(Edition edition)
{ {
setWindowTitle(getEditionName(edition)); setWindowTitle(m_SubscriptionManager->getEditionName (edition));
if (m_AppConfig->getCryptoEnabled()) { if (m_AppConfig->getCryptoEnabled()) {
m_pSslCertificate = new SslCertificate(this); m_pSslCertificate = new SslCertificate(this);
m_pSslCertificate->generateCertificate(); m_pSslCertificate->generateCertificate();
@ -1050,8 +1054,19 @@ void MainWindow::setEdition(Edition edition)
void MainWindow::beginTrial(bool isExpiring) void MainWindow::beginTrial(bool isExpiring)
{ {
if (isExpiring) { if (isExpiring) {
QString expiringNotice = "<html><head/><body><p><span style=\""
"font-weight:600;\">%1</span> days of "
"your Synergy Pro trial remain. <a href="
"\"http://symless.com/pricing?src=gui\">"
"<span style=\"text-decoration: underline;"
" color:#0000ff;\">Buy now!</span></a>"
"</p></body></html>";
expiringNotice = expiringNotice.arg
(m_SubscriptionManager->serialKey().daysLeft(::time(0)));
this->m_trialLabel->setText(expiringNotice);
this->m_trialWidget->show(); this->m_trialWidget->show();
} }
setWindowTitle (m_SubscriptionManager->activeEditionName());
} }
void MainWindow::endTrial(bool isExpired) void MainWindow::endTrial(bool isExpired)
@ -1059,6 +1074,7 @@ void MainWindow::endTrial(bool isExpired)
if (!isExpired) { if (!isExpired) {
this->m_trialWidget->hide(); this->m_trialWidget->hide();
} }
setWindowTitle (m_SubscriptionManager->activeEditionName());
} }
void MainWindow::updateLocalFingerprint() void MainWindow::updateLocalFingerprint()

View File

@ -43,19 +43,6 @@ void setIndexFromItemData(QComboBox* comboBox, const QVariant& itemData)
} }
} }
QString
getEditionName (int edition) {
if (edition == kBasic) {
return "Synergy Basic";
}
else if (edition == kPro) {
return "Synergy Pro";
}
else {
return "Synergy (UNREGISTERED)";
}
}
QString hash(const QString& string) QString hash(const QString& string)
{ {
QByteArray data = string.toUtf8(); QByteArray data = string.toUtf8();

View File

@ -29,4 +29,3 @@ QString hash(const QString& string);
QString getFirstMacAddress(); QString getFirstMacAddress();
qProcessorArch getProcessorArch(); qProcessorArch getProcessorArch();
QString getOSInformation(); QString getOSInformation();
QString getEditionName (int edition);

View File

@ -20,6 +20,7 @@
#include "AppConfig.h" #include "AppConfig.h"
#include <ctime> #include <ctime>
#include <stdexcept> #include <stdexcept>
#include <utility>
#include <QThread> #include <QThread>
SubscriptionManager::SubscriptionManager(AppConfig* appConfig) : SubscriptionManager::SubscriptionManager(AppConfig* appConfig) :
@ -28,18 +29,24 @@ SubscriptionManager::SubscriptionManager(AppConfig* appConfig) :
try { try {
setSerialKey(m_AppConfig->serialKey()); setSerialKey(m_AppConfig->serialKey());
} catch (...) { } catch (...) {
/* Remove garbage serial keys from the registry */
m_AppConfig->setSerialKey(""); m_AppConfig->setSerialKey("");
m_AppConfig->setEdition(kUnregistered);
m_AppConfig->saveSettings(); m_AppConfig->saveSettings();
} }
} }
SerialKey std::pair<bool, QString>
SubscriptionManager::setSerialKey(QString serialKeyString) SubscriptionManager::setSerialKey(QString serialKeyString)
{ {
std::pair<bool, QString> ret (true, "");
SerialKey serialKey (serialKeyString.toStdString()); SerialKey serialKey (serialKeyString.toStdString());
if (!serialKey.isValid (::time(0))) { if (serialKey.isExpired(::time(0))) {
throw std::runtime_error ("Invalid serial key"); ret.first = false;
} ret.second = "Serial key expired";
return ret;
}
if (serialKey != m_serialKey) { if (serialKey != m_serialKey) {
using std::swap; using std::swap;
@ -65,15 +72,28 @@ SubscriptionManager::setSerialKey(QString serialKeyString)
m_AppConfig->saveSettings(); m_AppConfig->saveSettings();
} }
return serialKey; return ret;
} }
Edition SubscriptionManager::activeLicense() const Edition
SubscriptionManager::activeEdition() const
{ {
return m_serialKey.edition(); return m_serialKey.edition();
} }
void SubscriptionManager::update() const QString
SubscriptionManager::activeEditionName() const
{
return getEditionName(activeEdition(), m_serialKey.isTrial());
}
SerialKey
SubscriptionManager::serialKey() const
{
return m_serialKey;
}
void SubscriptionManager::refresh() const
{ {
emit serialKeyChanged (m_serialKey); emit serialKeyChanged (m_serialKey);
emit editionChanged (m_serialKey.edition()); emit editionChanged (m_serialKey.edition());
@ -84,7 +104,27 @@ void SubscriptionManager::update() const
void SubscriptionManager::skipActivation() void SubscriptionManager::skipActivation()
{ {
notifyActivation ("skip:unknown"); notifyActivation ("skip:unknown");
}
QString
SubscriptionManager::getEditionName(Edition const edition, bool trial)
{
std::string name ("Synergy ");
switch (edition) {
case kUnregistered:
name += "(UNREGISTERED)";
return QString::fromUtf8 (name.c_str(), name.size());
case kBasic:
name += "Basic";
break;
default:
name += "Pro";
}
if (trial) {
name += " (Trial)";
}
return QString::fromUtf8 (name.c_str(), name.size());
} }
void SubscriptionManager::notifyActivation(QString identity) void SubscriptionManager::notifyActivation(QString identity)

View File

@ -20,6 +20,7 @@
#include <QObject> #include <QObject>
#include <SerialKey.h> #include <SerialKey.h>
#include <ActivationNotifier.h> #include <ActivationNotifier.h>
#include <utility>
class AppConfig; class AppConfig;
@ -29,10 +30,13 @@ class SubscriptionManager: public QObject
public: public:
SubscriptionManager(AppConfig* appConfig); SubscriptionManager(AppConfig* appConfig);
SerialKey setSerialKey(QString serialKey); std::pair<bool, QString> setSerialKey(QString serialKey);
void update() const; void refresh() const;
Edition activeLicense() const; Edition activeEdition() const;
QString activeEditionName() const;
SerialKey serialKey() const;
void skipActivation(); void skipActivation();
static QString getEditionName(Edition edition, bool trial = false);
private: private:
void notifyActivation(QString identity); void notifyActivation(QString identity);

View File

@ -22,6 +22,9 @@
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
#include <climits> #include <climits>
#include <sstream>
#include <iomanip>
#include <stdexcept>
using namespace std; using namespace std;
@ -47,6 +50,9 @@ SerialKey::SerialKey(std::string serial) :
if (!plainText.empty()) { if (!plainText.empty()) {
parse(plainText); parse(plainText);
} }
if (!m_valid) {
throw std::runtime_error ("Invalid serial key");
}
} }
bool bool
@ -105,7 +111,51 @@ SerialKey::isTrial() const
Edition Edition
SerialKey::edition() const SerialKey::edition() const
{ {
return m_edition; return m_edition;
}
std::string
SerialKey::editionString() const
{
switch (edition()) {
case kBasic:
return "basic";
case kPro:
return "pro";
default: {
std::ostringstream oss;
oss << static_cast<int>(edition());
return oss.str();
}
}
}
static std::string
hexEncode (std::string const& str) {
std::ostringstream oss;
for (size_t i = 0; i < str.size(); ++i) {
int c = str[i];
oss << std::setfill('0') << std::hex << std::setw(2)
<< std::uppercase;
oss << c;
}
return oss.str();
}
std::string
SerialKey::toString() const
{
std::ostringstream oss;
oss << "v2;";
oss << (isTrial() ? "trial" : "lifetime") << ";";
oss << editionString() << ";";
oss << m_name << ";";
oss << m_userLimit << ";";
oss << m_email << ";";
oss << m_company << ";";
oss << m_warnTime << ";";
oss << m_expireTime;
return hexEncode(oss.str());
} }
time_t time_t
@ -118,10 +168,16 @@ SerialKey::daysLeft(time_t currentTime) const
timeLeft = m_expireTime - currentTime; timeLeft = m_expireTime - currentTime;
} }
unsigned long long dayLeft = 0; unsigned long long daysLeft = 0;
dayLeft = timeLeft % day != 0 ? 1 : 0; daysLeft = timeLeft % day != 0 ? 1 : 0;
return timeLeft / day + dayLeft; return timeLeft / day + daysLeft;
}
std::string
SerialKey::email() const
{
return m_email;
} }
std::string std::string
@ -208,7 +264,7 @@ SerialKey::parse(std::string plainSerial)
} }
Edition Edition
SerialKey::parseEdition(std::string editionStr) SerialKey::parseEdition(std::string const& editionStr)
{ {
Edition e = kBasic; Edition e = kBasic;
if (editionStr == "pro") { if (editionStr == "pro") {

View File

@ -36,12 +36,15 @@ public:
bool isExpired(time_t currentTime) const; bool isExpired(time_t currentTime) const;
bool isTrial() const; bool isTrial() const;
time_t daysLeft(time_t currentTime) const; time_t daysLeft(time_t currentTime) const;
std::string email() const;
Edition edition() const; Edition edition() const;
std::string toString() const;
private: private:
std::string decode(const std::string& serial) const; std::string decode(const std::string& serial) const;
void parse(std::string plainSerial); void parse(std::string plainSerial);
Edition parseEdition(std::string editionStr); Edition parseEdition(const std::string& editionStr);
std::string editionString() const;
#ifdef TEST_ENV #ifdef TEST_ENV
private: private: