Skip to content

Commit

Permalink
Rewrite generation of matches, clean up messy code sections, improve …
Browse files Browse the repository at this point in the history
…performance
  • Loading branch information
alex1701c committed Jul 18, 2019
1 parent 7e53412 commit bcb11e9
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 84 deletions.
75 changes: 30 additions & 45 deletions src/Match.cpp
Original file line number Diff line number Diff line change
@@ -1,65 +1,50 @@
#include "Match.h"
#include "Status.h"
#include <Plasma>
#include <KSharedConfig>
#include <KConfigGroup>
#include <krunner/querymatch.h>

void Match::generateOptions(Plasma::AbstractRunner *runner, QList<Plasma::QueryMatch> &matches,
KConfigGroup &configGroup, Status &vpnStatus, QString &term) {

matches.append(
createMatch(runner, configGroup, vpnStatus.formatString(configGroup.readEntry("status", "%STATUS")), "status", 0.5)
);
generateConnectionOptions(runner, matches, configGroup, vpnStatus, term);
#include <QDebug>

QList<Match> Match::generateOptions(Status &vpnStatus, QString &term) {
QList<Match> matches;
const auto config = KSharedConfig::openConfig("krunnerrc")->group("Runners").group("NordVPN");
matches.append(Match(vpnStatus.formatString(config.readEntry("status", "%STATUS")), "status", 0.5));
matches.append(generateConnectionOptions(vpnStatus, config, term));
return matches;
}

void Match::generateConnectionOptions(Plasma::AbstractRunner *runner, QList<Plasma::QueryMatch> &matches,
KConfigGroup &configGroup, Status &vpnStatus, QString &term) {
QList<Match> Match::generateConnectionOptions(Status &vpnStatus, const KConfigGroup &config, QString &term) {
QString target;
// Disconnect/Connect options
QList<Match> matches;

if (vpnStatus.connectionExists()) {
// Disconnect option always shown, relevance differs
int relevanceDisconnect = 0;
if (term.contains(QRegExp("vpn d(isconnect)?[ ]*$"))) {
if (term.contains(QRegExp("vpn d(isconnect)? *$"))) {
relevanceDisconnect = 1;
}
matches.append(createMatch(runner, configGroup, "Disconnect", "disconnect", relevanceDisconnect));
matches.append(Match("Disconnect", "disconnect", relevanceDisconnect));
} else {
target = Status::evalConnectQuery(term, configGroup.readEntry("default", "US")).toUpper();
matches.append(createMatch(
runner, configGroup, QString("Connect To " + target), QString("nordvpn connect " + target), 1)
);
// Connect to new
target = Status::evalConnectQuery(term, config.readEntry("default", "US")).toUpper();
matches.append(Match(QString("Connect To " + target), QString("nordvpn connect " + target), 1));
}
// Reconnect to current/other options
if (vpnStatus.connectionExists() && (term.startsWith("vpn reconnect") || term.startsWith("nordvpn reconnect"))) {
target = Status::evalConnectQuery(term, "");
bool textOnly = target.contains(QRegExp("[a-zA-z ]{2,50}$"));
bool sameStart = QString((vpnStatus.country + vpnStatus.server)).replace(" ", "").toUpper()
.startsWith(target.replace(" ", "").toUpper());
bool countryOnly = target.contains(QRegExp("[a-zA-z ]{2,50}$"));
bool sameStart = QString((vpnStatus.country + vpnStatus.server)).replace(" ", "")
.startsWith(target.replace(" ", ""), Qt::CaseInsensitive);
bool emptyTarget = target.replace(" ", "").isEmpty();

if ((sameStart && (textOnly || target.endsWith(vpnStatus.server))) || target.replace(" ", "").isEmpty()) {
// [The address from the status startswith the one of the query &&
// (the server addresses match exactly || no server address specified)] || no targeted address
if (target.isEmpty()) {
target = vpnStatus.country + vpnStatus.server;
} else if (textOnly) {
target += vpnStatus.server;
}
matches.append(createMatch(runner, configGroup, "Reconnect To Current ",
QString("nordvpn d > /dev/null 2>&1 ;nordvpn c " + target), 1));
if (emptyTarget || (sameStart && countryOnly) ||
target.toLower() == QString(vpnStatus.country + vpnStatus.status).toLower()) {
// Target is empty or the connection and target country are the same or the connection and target are exactly the same
if (target.isEmpty()) target = vpnStatus.country + vpnStatus.server;
else if (countryOnly) target += vpnStatus.server;
matches.append(Match("Reconnect To Current", "nordvpn d > /dev/null 2>&1 ;nordvpn c " + target, 1));
} else {
matches.append(createMatch(runner, configGroup, QString("Reconnect To " + target),
QString("nordvpn d > /dev/null 2>&1 ;nordvpn c " + target), 1));
matches.append(Match("Reconnect To " + target, "nordvpn d > /dev/null 2>&1 ;nordvpn c " + target, 1));
}
}
}

Plasma::QueryMatch Match::createMatch(Plasma::AbstractRunner *runner, KConfigGroup &configGroup,
const QString &text, const QString &data, double relevance) {
Plasma::QueryMatch match(runner);
match.setIconName(configGroup.readEntry("icon", "/usr/share/icons/nordvpn.png"));
match.setText(text);
match.setData(data);
match.setRelevance(relevance);
return match;
}
return matches;
}
19 changes: 10 additions & 9 deletions src/Match.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <utility>

#ifndef NORDVPN_MATCH_H
#define NORDVPN_MATCH_H

Expand All @@ -7,18 +9,17 @@

class Match {
public:
QString text;
QString data;
float relevance = 0;

Match() = default;

static void
generateOptions(Plasma::AbstractRunner *runner, QList<Plasma::QueryMatch> &matches, KConfigGroup &configGroup,
Status &vpnStatus, QString &term);
Match(QString text, QString data, float relevance) : text(std::move(text)), data(std::move(data)), relevance(relevance) {}

static void
generateConnectionOptions(Plasma::AbstractRunner *runner, QList<Plasma::QueryMatch> &matches,
KConfigGroup &configGroup, Status &vpnStatus, QString &term);
static QList<Match> generateOptions(Status &vpnStatus, QString &term);

static Plasma::QueryMatch
createMatch(Plasma::AbstractRunner *runner, KConfigGroup &configGroup, const QString &text, const QString &data,
double relevance);
static QList<Match> generateConnectionOptions(Status &vpnStatus, const KConfigGroup &config, QString &term);
};


Expand Down
13 changes: 7 additions & 6 deletions src/Status.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
#include <QtCore/QRegExp>
#include <KConfigCore/KSharedConfig>
#include <KConfigCore/KConfigGroup>
#include <iostream>
#include <QtCore/QProcess>
#include <QtGui/QtGui>
#include "Status.h"

void Status::extractConnectionInformation() {
Expand All @@ -28,9 +26,10 @@ bool Status::connectionExists() {
return status.startsWith("Status: Connect") || status == "Status: Reconnecting";
}

QString Status::evalConnectQuery(QString &term, QString target) {
QString Status::evalConnectQuery(QString &term, QString defaultTarget) {
QString target;
// Returns extracted target from normal or reconnect queries, rejects disconnect query
if (!term.contains("reconnect")) {// No reconnect in term
if (!term.contains("reconnect")) {
if (term.contains(QRegExp("vpn d[ ]*$")) || term.contains("vpn di")) {
// Rejects for example vpn d, vpn disconnect, vpn dis
return target;
Expand All @@ -45,11 +44,13 @@ QString Status::evalConnectQuery(QString &term, QString target) {
QRegExp regexReconnect("vpn reconnect ([a-zA-Z _]+[\\da-zA-Z_]*)$");
regexReconnect.indexIn(term);
QStringList reconnectRes = regexReconnect.capturedTexts();
if (reconnectRes.size() == 2 && !reconnectRes.at(1).isEmpty()) {
if (!reconnectRes.at(1).isEmpty()) {
target = reconnectRes.at(1).toUpper();
}
}

if (target.isEmpty() || target.size() == 1) return defaultTarget;

return target;
}

Expand All @@ -64,7 +65,7 @@ QString Status::getRawConnectionStatus(const QString &statusSource) {
return out;
}

Status Status::objectFromRawData(const QString &statusData) {
Status Status::objectFromRawData(const QString &statusData) {
Status status;
for (const auto &line:statusData.split('\n')) {
if (line.startsWith("Status:")) {
Expand Down
2 changes: 1 addition & 1 deletion src/Status.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Status {

bool connectionExists();

static QString evalConnectQuery(QString &term, QString target = "");
static QString evalConnectQuery(QString &term, QString defaultTarget = "");

static QString getRawConnectionStatus(const QString &statusSource);

Expand Down
50 changes: 28 additions & 22 deletions src/nordvpn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ NordVPN::NordVPN(QObject *parent, const QVariantList &args)
}

NordVPN::~NordVPN() = default;
// TODO Better solution to create matches

void NordVPN::init() {
reloadConfiguration();
connect(this, SIGNAL(prepare()), this, SLOT(prepareForMatchSession()));
connect(this, SIGNAL(teardown()), this, SLOT(matchSessionFinished()));
}

void NordVPN::reloadConfiguration() {
vpnConfigGroup = KSharedConfig::openConfig("krunnerrc")->group("Runners").group("NordVPN");
config = KSharedConfig::openConfig("krunnerrc")->group("Runners").group("NordVPN");
statusSource = config.readEntry("source", "nordvpn status");

statusSource = vpnConfigGroup.readEntry("source", "nordvpn status");
//region syntax
QList<Plasma::RunnerSyntax> syntaxes;
syntaxes.append(Plasma::RunnerSyntax("vpn us", "Connect option to United States, server is chosen by NordVPN"));
Expand Down Expand Up @@ -63,15 +63,13 @@ void NordVPN::prepareForMatchSession() {

void NordVPN::matchSessionFinished() {
if (!wasActive) return;
if (vpnConfigGroup.readEntry("clean_history", "true") == "true") {
if (config.readEntry("clean_history", "true") == "true") {
wasActive = false;
QString history = vpnConfigGroup.parent().parent().group("General").readEntry("history");
QString filteredHistory = history
.replace(QRegExp(R"((?:nord)?vpn set[^,]*,?)"), "")
.replace(QRegExp(R"((?:nord)?vpn d(?:isconnect)?[^ek],?)"), "");
if (filteredHistory.size() == vpnConfigGroup.parent().parent().group("General").readEntry("history").size()) {
return;
}
QString history = config.parent().parent().group("General").readEntry("history");
const int historySize = history.size();
QString filteredHistory = history.replace(QRegExp(R"((?:nord)?vpn d(?:isconnect)?[^ek],?)"), "");
if (filteredHistory.size() == historySize) return;

QFile f(QString(getenv("HOME")) + "/.config/krunnerrc");
if (f.open(QIODevice::ReadWrite)) {
QString s;
Expand Down Expand Up @@ -100,30 +98,38 @@ void NordVPN::match(Plasma::RunnerContext &context) {
if (!term.startsWith("vpn") && !term.startsWith("nordvpn")) return;
if (vpnStatus.status == "Error") return;

Match::generateOptions(this, matches, vpnConfigGroup, vpnStatus, term);

QList<Match> matchList = Match::generateOptions(vpnStatus, term);
for (const auto &m:matchList) {
Plasma::QueryMatch match(this);
match.setText(m.text);
match.setData(m.data);
match.setRelevance(m.relevance);
match.setIconName(config.readEntry("icon", "/usr/share/icons/nordvpn.png"));
matches.append(match);
}
context.addMatches(matches);
}

void NordVPN::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) {
Q_UNUSED(context)
wasActive = true;

QString payload = match.data().toString();
const QString iconPath = vpnConfigGroup.readEntry("icon", "/usr/share/icons/nordvpn.png");
const QString changeScript = vpnConfigGroup.readEntry("script", "");
const QString iconPath = config.readEntry("icon", "/usr/share/icons/nordvpn.png");
const QString changeScript = config.readEntry("script", "");
QString cmd;

bool notify = vpnConfigGroup.readEntry("notify", "true") == "true";
QString startFilter(R"( | tr -d '/\-|\\' | tail -2 | cut -d '(' -f 1 |xargs -d '\n' notify-send --icon <ICON> )");
if (!notify) startFilter = " 2>&1 > /dev/null";
bool notify = config.readEntry("notify", "true") == "true";
QString notifyPipes(R"( | tr -d '/\-|\\' | tail -2 | cut -d '(' -f 1 |xargs -d '\n' notify-send --icon <ICON> )");
if (!notify) notifyPipes = " 2>&1 > /dev/null";
if (payload == "disconnect") {
wasActive = true;
cmd = R"($( nordvpn d PIPES; <SCRIPT>) )";
cmd.replace("PIPES", startFilter);
cmd.replace("PIPES", notifyPipes);
} else if (payload == "status") {
cmd = QString("$(vpnStatus=$(nordvpn status 2>&1 | grep -i -E '%1');notify-send \"$vpnStatus\" --icon <ICON> ) ")
.arg(vpnConfigGroup.readEntry("status_keys", "Status|Current server|Transfer|IP"));
.arg(config.readEntry("status_keys", "Status|Current server|Transfer|IP"));
} else {
cmd = "$( " + payload + startFilter + "; <SCRIPT> )";// Disconnect or connect
cmd = "$( " + payload + notifyPipes + "; <SCRIPT> )";// Disconnect or connect
}
cmd = cmd.replace("<ICON>", iconPath).replace("<SCRIPT>", changeScript);
system(qPrintable(cmd + " 2>&1 &"));
Expand Down
2 changes: 1 addition & 1 deletion src/nordvpn.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Q_OBJECT

~NordVPN() override;

KConfigGroup vpnConfigGroup;
KConfigGroup config;
Status vpnStatus;
QString statusSource;
bool wasActive = false;
Expand Down

0 comments on commit bcb11e9

Please sign in to comment.