6 Commits
12 changed files with 95 additions and 106 deletions
+2
View File
@@ -37,3 +37,5 @@ Makefile*
# QtCtreator CMake
CMakeLists.txt.user*
msvc_make.bat
+1
View File
@@ -39,3 +39,4 @@ RESOURCES += \
resource.qrc
RC_ICONS = icons\favicon.ico
+4 -7
View File
@@ -1,4 +1,4 @@
#include "maintray.h"
#include "maintray.h"
#include <QApplication>
#include <QTranslator>
#include <QFont>
@@ -6,16 +6,13 @@
int main(int argc, char *argv[])
{
QTranslator t;
t.load(QString(":/translations/qt_zh_CN.qm"));
QApplication a(argc, argv);
a.installTranslator(&t);
a.setQuitOnLastWindowClosed(false);
a.setApplicationName(QObject::tr("NEU-Monitor"));
a.setWindowIcon(QIcon(QObject::tr(":/icon/favicon.ico")));
QFontDatabase::addApplicationFont(QString(":/resource/SourceHanSansCN-Regular.otf"));
QFont font("SourceHan", 9);
a.setFont(font);
// QFontDatabase::addApplicationFont(QString(":/resource/SourceHanSansCN-Regular.otf"));
// QFont font("SourceHanSourceHanSansCN", 9);
// a.setFont(font);
// a.setFont(QFont("Microsoft YaHei", 9));
MainTray *tray = new MainTray();
QObject::connect(tray, &MainTray::exit, &a, &QApplication::quit);
+51 -72
View File
@@ -1,35 +1,30 @@
#include "maintray.h"
#include "maintray.h"
MainTray::MainTray(QObject *parent) : QSystemTrayIcon(parent),
//初始化menu
menu(new QMenu()),
infoMenu(new QMenu()),
settingsMenu(new QMenu()),
//初始化settings
settings(QSettings::IniFormat, QSettings::UserScope, "Cai.MY", "NEU-Monitor"),
user(settings.value("id", "").toByteArray()),
passwd(QByteArray::fromBase64(settings.value("password", "").toByteArray())),
totalTraffic(settings.value("total traffic", 0).toInt()),
isMobile(settings.value("isMobile", false).toBool()),
forceLogin(settings.value("forceLogin", false).toBool()),
opWindow(user, passwd, totalTraffic),
logFileName("NEU_Monitor.log"),
logFile(logFileName, this)
//初始化menu
menu(new QMenu()),
infoMenu(new QMenu()),
settingsMenu(new QMenu()),
//初始化settings
settings(QSettings::IniFormat, QSettings::UserScope, "Cai.MY", "NEU-Monitor"),
user(settings.value("id", "").toByteArray()),
passwd(QByteArray::fromBase64(settings.value("password", "").toByteArray())),
totalTraffic(settings.value("total traffic", 0).toInt()),
isMobile(settings.value("isMobile", false).toBool()),
forceLogin(settings.value("forceLogin", false).toBool()),
opWindow(user, passwd, totalTraffic)
{
openLogFile();
opWindow.hide();
setIcon(QIcon(olIconPath));
netctrl = new NetController(user, passwd, this); //passwd为解密后密码
connect(netctrl, &NetController::sendLog, this, &MainTray::writeLog);
netctrl->setUsername(user);
netctrl->setPassword(passwd);
netctrl->setTotalTraffic(totalTraffic);
netctrl->setMobile(isMobile);
writeLog(tr("Load username[") + user + tr("] traffic[") + QString::number(totalTraffic) + tr("]."));
connect(&opWindow, &OptionsWindow::saveSettings, this, &MainTray::updateUserInfo);
//连接controller状态改变信号
connect(netctrl, &NetController::sendState, this, &MainTray::handleState);
@@ -83,7 +78,6 @@ MainTray::MainTray(QObject *parent) : QSystemTrayIcon(parent),
muteAction->setToolTip(tr("勿扰模式下不会发出通知"));
connect(loginAction, &QAction::triggered, this, [this]() {
writeLog(tr("Login triggered."));
isForceLogin = true;
// netctrl->sendLogoutRequest(true);
if (forceLogin) {
@@ -94,41 +88,34 @@ MainTray::MainTray(QObject *parent) : QSystemTrayIcon(parent),
isForceLogout = false;
});
connect(logoutAction, &QAction::triggered, this, [this]() {
writeLog(tr("Logout triggered."));
netctrl->sendLogoutRequest(currentState != NetController::Online); //若不在线则断开全部链接
isForceLogout = true;
});
connect(autoLogin, &QAction::toggled, this, [this](bool set) {
writeLog(tr("Autologin turn ") + (set ? tr("[on].") : tr("[off].")));
settings.setValue("isAutoLogin", set);
isForceLogout = false;
showToolTip(currentState);
});
connect(muteAction, &QAction::toggled, this, [this](bool set) {
writeLog(tr("Mute mode turn ") + (set ? tr("[on].") : tr("[off].")));
settings.setValue("isMute", set);
});
connect(bootAction, &QAction::toggled, this, [this](bool set) {
writeLog(tr("Boot with system turn ") + (set ? tr("[on].") : tr("[off].")));
settings.setValue("isOnBoot", set);
setAutoStart(set);
});
connect(optionsAction, &QAction::triggered, this, [this]() { showOptions(); });
connect(aboutAction, &QAction::triggered, this, &MainTray::showAbout);
connect(quitAction, &QAction::triggered, this, [this]() {
writeLog(tr("Exit.\n\n"));
emit exit();
});
connect(mobileAction, &QAction::triggered, this, [this](bool set) {
writeLog(tr("Mobile model turn ") + tr(set? "[on].": "[off]."));
settings.setValue("isMobile", set);
isMobile = set;
netctrl->setMobile(set);
});
connect(forceLoginAction, &QAction::triggered, this, [this](bool set) {
writeLog(tr("Force Login turn ") + tr(set? "[on].": "[off]."));
settings.setValue("forceLogin", set);
forceLogin = set;
});
@@ -183,7 +170,6 @@ MainTray::~MainTray()
delete menu;
delete infoMenu;
delete autoLoginTimer;
logFile.close();
}
void MainTray::showToolTip(NetController::State state)
@@ -209,8 +195,6 @@ void MainTray::showToolTip(NetController::State state)
case NetController::WrongPass:
tooltipString += tr("当前状态:密码错误");
break;
default:
break;
}
tooltipString += tr("(") + (netctrl->getMobile() ? tr("Mobile") : tr("PC")) + tr(")");
tooltipString += tr("\n自动登陆:");
@@ -238,7 +222,6 @@ void MainTray::handleActivated(QSystemTrayIcon::ActivationReason reason)
{
case QSystemTrayIcon::DoubleClick:
case QSystemTrayIcon::MiddleClick:
writeLog(tr("Double click TrayIcon."));
if (currentState == NetController::Offline)
{
loginAction->trigger();
@@ -258,22 +241,24 @@ void MainTray::handleActivated(QSystemTrayIcon::ActivationReason reason)
void MainTray::showOptions()
{
writeLog(tr("Open options window."));
opWindow.show();
}
void MainTray::showAbout()
{
writeLog(tr("Open about window."));
QMessageBox *aboutWindow = new QMessageBox();
aboutWindow->setStandardButtons(QMessageBox::Ok);
aboutWindow->setText(tr("<h1>NEU-Monitor</h1>"
"<h3>Version: 1.4.1</h3>"
"<p>Based on Qt 5.11.1 (MinGW 5.3.0, 32bit)</p>"
"Source Code: <a href=\"https://github.com/c-my/NEU-Monitor\">https://github.com/c-my/NEU-Monitor</a><br/>"
"Email: <address>"
"<a href=\"mailto:cmy1113@yeah.net?subject=Neu-Monitor-v1.4.1 Feedback\">Cai.MY</a>"
"</address>"));
"<p>Based on Qt ")+getQtVersion() + tr("(") +
getCompilerVersion() +
tr(
")</p>"
"Configuration file path: <a href = \"") + settings.fileName() +
tr("\">") + settings.fileName() + tr("</a><br/>Source Code: <a href=\"https://github.com/c-my/NEU-Monitor\">https://github.com/c-my/NEU-Monitor</a><br/>"
"Email: <address>"
"<a href=\"mailto:cmy1113@yeah.net?subject=Neu-Monitor-v1.4.1 Feedback\">Cai.MY</a>"
"</address>"));
aboutWindow->setAttribute(Qt::WA_DeleteOnClose);
aboutWindow->setModal(false);
aboutWindow->show();
@@ -330,24 +315,24 @@ void MainTray::setAutoStart(bool set)
#endif
}
void MainTray::openLogFile()
QString MainTray::getQtVersion()
{
if (!logFile.open(QIODevice::Append | QIODevice::Text))
{
if (!muteAction->isChecked())
{
showMessage(tr("警告"), tr("日志文件打开失败"));
}
// return;
}
writeLog(tr("\n=================================================="), false);
writeLog(tr("Open logfile [") + logFile.fileName() + tr("] successfully."));
logFile.close();
return QString::number(QT_VERSION_MAJOR)+tr(".")+QString::number(QT_VERSION_MINOR)+tr(".")+QString::number(QT_VERSION_PATCH);
}
QString MainTray::getCompilerVersion()
{
#ifdef __GNUC__
return tr("GCC ")QString::number(__GNUC__)+tr(".")+QString::number(__GNUC_MINOR__)+tr(".")+QString::number(__GNUC_PATCHLEVEL__);
#endif
#ifdef _MSC_VER
return tr("MSVC ") + QString::number(_MSC_FULL_VER);
#endif
}
void MainTray::updateUserInfo(QByteArray id, QByteArray pass, int traffic) //pass为未加密的密码
{
writeLog(tr("Set username[") + id + tr("]; Traffic: [") + QString::number(traffic) + tr("]."));
logoutAction->trigger(); //注销当前via old info
netctrl->setUsername(id);
netctrl->setPassword(pass);
@@ -371,7 +356,6 @@ void MainTray::handleState(NetController::State state)
switch (state)
{
case NetController::Online:
writeLog(tr("Old state: [") + QString::number(currentState) + tr("]; New state: [") + QString::number(state) + tr("]."));
isForceLogin = false;
setIcon(QIcon(olIconPath));
if (!muteAction->isChecked())
@@ -381,7 +365,6 @@ void MainTray::handleState(NetController::State state)
case NetController::Offline:
if (currentState == NetController::WrongPass || currentState == NetController::Owed)
return;
writeLog(tr("Old state: [") + QString::number(currentState) + tr("]; New state: [") + QString::number(state) + tr("]."));
setIcon(QIcon(offIconPath));
if (!muteAction->isChecked())
showMessage(tr("网络已断开"), tr("校园网已注销"), this->icon(), msgDur);
@@ -394,14 +377,12 @@ void MainTray::handleState(NetController::State state)
currentState = state;
break;
case NetController::Disconnected:
writeLog(tr("Old state: [") + QString::number(currentState) + tr("]; New state: [") + QString::number(state) + tr("]."));
setIcon(QIcon(offIconPath));
if (!muteAction->isChecked())
showMessage(tr("网络已断开"), tr("无法连接至校园网"), this->icon(), msgDur);
currentState = state;
break;
case NetController::WrongPass:
writeLog(tr("Old state: [") + QString::number(currentState) + tr("]; New state: [") + QString::number(state) + tr("]."));
setIcon(QIcon(offIconPath));
if (!muteAction->isChecked())
showMessage(tr("登陆失败"), tr("密码错误"), this->icon(), msgDur);
@@ -409,7 +390,6 @@ void MainTray::handleState(NetController::State state)
break;
case NetController::Owed:
setIcon(QIcon(offIconPath));
writeLog(tr("Old state: [") + QString::number(currentState) + tr("]; New state: [") + QString::number(state) + tr("]."));
if (!muteAction->isChecked())
showMessage(tr("登陆失败"), tr("已欠费"), this->icon(), msgDur);
currentState = state;
@@ -417,19 +397,18 @@ void MainTray::handleState(NetController::State state)
default:
break;
}
writeLog(tr("State change to [") + QString::number(currentState) + tr("]."));
showToolTip(state);
}
}
void MainTray::handleInfo(QString byte, QString sec, QString balance, QString ip)
{
QString mbString = QString::number(byte.toDouble() / 1048576.0, 'f', 2);
QString mbString = QString::number(byte.toDouble() / 1000000.0, 'f', 2);
QString gbString = QString::number(byte.toDouble() / 1000000000.0, 'f', 2);
QString leftoverString = QString::number(totalTraffic - byte.toDouble() / 1000000000.0, 'f', 2);
double totalSec = sec.toDouble();
double hour = (totalSec / 3600);
int min = ((totalSec - hour * 3600) / 60);
int min = int((totalSec - hour * 3600) / 60);
QString second = QString::number(totalSec - hour * 3600 - min * 60);
mbAction->setText(tr("已用流量:\t") + mbString + tr(" M"));
timeAction->setText(tr("已用时长:\t") + QString::number(hour, 'f', 2) + tr(" 小时") /*+ ":" +QString::number(min) + ":" + second*/);
@@ -438,7 +417,7 @@ void MainTray::handleInfo(QString byte, QString sec, QString balance, QString ip
if (!hasWarned && totalTraffic > 0)
{
hasWarned = true;
if (byte.toDouble() / 1048576.0 > totalTraffic * 1024)
if (byte.toDouble() / 1000000.0 > totalTraffic * 1024)
{ //流量已超
trafficstate = Over;
if (!muteAction->isChecked())
@@ -446,7 +425,7 @@ void MainTray::handleInfo(QString byte, QString sec, QString balance, QString ip
showMessage(tr("流量警告"), tr("本月流量已超"), QSystemTrayIcon::Warning);
});
}
else if (byte.toDouble() / 1048576.0 + 5000 > totalTraffic * 1024)
else if (byte.toDouble() / 1000000.0 + 5000 > totalTraffic * 1024)
{ //流量将超
trafficstate = Nearly;
if (!muteAction->isChecked())
@@ -458,14 +437,14 @@ void MainTray::handleInfo(QString byte, QString sec, QString balance, QString ip
}
}
void MainTray::writeLog(QString content, bool timeStamp)
{
if (!logFile.isOpen())
logFile.open(QIODevice::Append | QIODevice::Text);
if (timeStamp)
logFile.write(QDateTime::currentDateTime().toString("[yyyy.MM.dd hh:mm:ss] ").toUtf8());
logFile.write(content.toUtf8());
logFile.write(tr("\n").toUtf8());
// qDebug()<<"Write log"<<content;
logFile.close();
}
//void MainTray::writeLog(QString content, bool timeStamp)
//{
// if (!logFile.isOpen())
// logFile.open(QIODevice::Append | QIODevice::Text);
// if (timeStamp)
// logFile.write(QDateTime::currentDateTime().toString("[yyyy.MM.dd hh:mm:ss] ").toUtf8());
// logFile.write(content.toUtf8());
// logFile.write(tr("\n").toUtf8());
// // qDebug()<<"Write log"<<content;
// logFile.close();
//}
+7 -6
View File
@@ -1,6 +1,10 @@
#ifndef MAINTRAY_H
#ifndef MAINTRAY_H
#define MAINTRAY_H
#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif
#include <QObject>
#include <QSystemTrayIcon>
#include <QMenu>
@@ -47,9 +51,6 @@ private:
OptionsWindow opWindow;
QTimer *autoLoginTimer; //自动重连定时器
QString logFileName;
QFile logFile;
QString olIconPath = tr(":/icons/favicon.ico");
QString offIconPath = tr(":/icons/offline.ico");
@@ -69,6 +70,8 @@ private:
int msgDur = 500; //通知持续时间
int checkInterval = 1000; //查询状态定时器周期
inline QString getQtVersion();
inline QString getCompilerVersion();
signals:
void exit();
@@ -76,8 +79,6 @@ private slots:
void updateUserInfo(QByteArray id, QByteArray pass, int traffic);
void handleState(NetController::State state);
void handleInfo(QString mb, QString sec, QString balance, QString ip);
void openLogFile();
void writeLog(QString content, bool timeStamp = true);
};
#endif // MAINTRAY_H
+7 -8
View File
@@ -1,4 +1,4 @@
#include "netcontroller.h"
#include "netcontroller.h"
NetController::NetController(QByteArray id, QByteArray passwd, QObject *parent) : QObject(parent),
username(id), password(passwd), manager(this)
@@ -11,7 +11,13 @@ NetController::NetController(QByteArray id, QByteArray passwd, QObject *parent)
desktopRequest.setRawHeader("Cache-Control", "max-age=0");
desktopRequest.setRawHeader("Origin", "http://ipgw.neu.edu.cn");
desktopRequest.setRawHeader("Upgrade-Insecure-Requests", "1");
#ifdef Q_OS_LINUX
desktopRequest.setRawHeader("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36");
#endif
#ifdef Q_OS_WIN32
desktopRequest.setRawHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36");
#endif
desktopRequest.setRawHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
desktopRequest.setRawHeader("Referer", "http://ipgw.neu.edu.cn/srun_portal_pc.php?ac_id=1&");
desktopRequest.setRawHeader("Accept-Encoding", "gzip, deflate");
@@ -46,8 +52,6 @@ void NetController::sendCheckRequest()
void NetController::sendLoginRequest()
{
sendLog(tr("Send login request. [") + username + tr("]"));
QByteArray loginParam;
loginParam.append("action=login&");
loginParam.append("nas_ip=&");
@@ -74,8 +78,6 @@ void NetController::sendLoginRequest()
void NetController::sendLogoutRequest(bool isAll)
{
sendLog(tr("Send logout request. [") + username + tr("]"));
QByteArray logoutParam;
logoutParam.append("action=logout&");
logoutParam.append("ajax=1&");
@@ -129,17 +131,14 @@ void NetController::handleResponse(QNetworkReply *reply)
QString loginPage(reply->readAll());
if (loginPage.contains(QString("已欠费")))
{ //欠费
sendLog(tr("Get [Owed] response."));
emit sendState(Owed);
}
else if (loginPage.contains("Password is error"))
{ //密码错误
sendLog(tr("Get [Wrong Password] response."));
emit sendState(WrongPass);
}
else if (loginPage.contains("网络已连接"))
{ //登陆成功
sendLog(tr("Get [Login success] response."));
emit sendState(Online);
}
}
+1 -2
View File
@@ -1,4 +1,4 @@
#ifndef NETCONTROLLER_H
#ifndef NETCONTROLLER_H
#define NETCONTROLLER_H
#include <QObject>
@@ -49,7 +49,6 @@ private:
signals:
void sendState(State newState);
void sendInfo(QString mb, QString sec, QString balance, QString ip);
void sendLog(QString content, bool timeStamp = true);
public slots:
void handleResponse(QNetworkReply *reply);
+15 -6
View File
@@ -1,4 +1,4 @@
#include "optionswindow.h"
#include "optionswindow.h"
OptionsWindow::OptionsWindow(QByteArray id, QByteArray pass, int traffic, QWidget *parent) : QMainWindow(parent)
{
@@ -13,27 +13,36 @@ OptionsWindow::OptionsWindow(QByteArray id, QByteArray pass, int traffic, QWidge
idEdit = new QLineEdit(this);
idEdit->setText(id);
idEdit->setPlaceholderText(tr("学(工)号"));
passwordEdit = new QLineEdit(this);
passwordEdit->setEchoMode(QLineEdit::Password);
passwordEdit->setContextMenuPolicy(Qt::NoContextMenu);
passwordEdit->setText(pass);
passwordEdit->setToolTip(tr("密码仅用于登陆"));
passwordEdit->setPlaceholderText(tr("请输入密码"));
// mobileCheck = new QCheckBox(tr("作为移动端登陆"), this);
// mobileCheck->setChecked(isMobile);
// mobileCheck->setToolTip(tr("实现PC多终端在线"));
trafficSpin = new QSpinBox(this);
trafficSpin->setValue(traffic);
trafficSpin->setToolTip(tr("0为无限制"));
trafficBox = new QComboBox(this);
trafficBox->setEditable(true);
trafficBox->setValidator(new QIntValidator(0, INT_MAX));
trafficBox->setToolTip(tr("0为无限制"));
trafficBox->addItem(tr("5"));
trafficBox->addItem(tr("25"));
trafficBox->addItem(tr("60"));
trafficBox->setCurrentText(QString::number(traffic));
trafficLabel = new QLabel(tr("流量(G)"), this);
trafficLabel->setToolTip(tr("在流量将要用尽时进行提醒"));
layout->addRow(tr("用户名"), idEdit);
layout->addRow(tr("密码"), passwordEdit);
layout->addRow(trafficLabel, trafficSpin);
layout->addRow(trafficLabel, trafficBox);
layout->setSpacing(20);
saveButton = new QPushButton("确定", this);
@@ -56,7 +65,7 @@ OptionsWindow::OptionsWindow(QByteArray id, QByteArray pass, int traffic, QWidge
connect(saveButton, &QPushButton::clicked, this, [this]() {
emit saveSettings(idEdit->text().toUtf8(),
passwordEdit->text().toUtf8(),
trafficSpin->value());
trafficBox->currentText().toInt());
});
connect(cancleButton, &QPushButton::clicked, this, &OptionsWindow::hide);
}
+7 -3
View File
@@ -1,16 +1,20 @@
#ifndef OPTIONSWINDOW_H
#ifndef OPTIONSWINDOW_H
#define OPTIONSWINDOW_H
#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif
#include <QMainWindow>
#include <QWidget>
#include <QTabWidget>
#include <QLineEdit>
#include <QSpinBox>
#include <QPushButton>
#include <QFormLayout>
#include <QVBoxLayout>
#include <QLabel>
#include <QCheckBox>
#include <QComboBox>
#include <QSettings>
class OptionsWindow : public QMainWindow
@@ -23,12 +27,12 @@ private:
QTabWidget *tabWidget;
QWidget *page1;
QLineEdit *idEdit, *passwordEdit;
QSpinBox *trafficSpin;
QPushButton *saveButton, *cancleButton;
QFormLayout *layout;
QVBoxLayout *vlayout;
QHBoxLayout *hlayout;
QCheckBox *mobileCheck;
QComboBox *trafficBox;
QLabel *trafficLabel;
View File
-2
View File
@@ -1,10 +1,8 @@
<RCC>
<qresource prefix="/icon"/>
<qresource prefix="/">
<file>translations/qt_zh_CN.qm</file>
<file>icons/favicon.ico</file>
<file>icons/offline.ico</file>
<file>resource/SourceHanSansCN-Regular.otf</file>
<file>qt/etc/qt.conf</file>
</qresource>
</RCC>
Binary file not shown.