131 lines
4 KiB
C++
131 lines
4 KiB
C++
#include "spacetray.h"
|
|
#include "themes/lock.h"
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
#include <QNetworkRequest>
|
|
#include <QAction>
|
|
#include <QCoreApplication>
|
|
#include <QImage>
|
|
#include <QPixmap>
|
|
#include <QDebug>
|
|
|
|
SpaceTray::SpaceTray(const QString &url, QObject *parent)
|
|
: QObject(parent),
|
|
m_statusUrl(url),
|
|
m_doorOpen(false),
|
|
m_oldDoorOpen(false),
|
|
m_doorLastChange(0),
|
|
m_spaceName("Unknown Space"),
|
|
m_firstRun(true)
|
|
{
|
|
// Initialize icons from raw data
|
|
QImage imgOpen(icon_open_data, 52, 48, 208, QImage::Format_RGBA8888);
|
|
m_iconOpen = QIcon(QPixmap::fromImage(imgOpen));
|
|
|
|
QImage imgClosed(icon_closed_data, 52, 48, 208, QImage::Format_RGBA8888);
|
|
m_iconClosed = QIcon(QPixmap::fromImage(imgClosed));
|
|
|
|
// Setup tray icon
|
|
m_trayIcon = new QSystemTrayIcon(this);
|
|
m_trayIcon->setIcon(m_iconClosed);
|
|
m_trayIcon->setVisible(true);
|
|
|
|
// Setup tray menu
|
|
m_trayMenu = new QMenu();
|
|
QAction *quitAction = m_trayMenu->addAction("Quit");
|
|
connect(quitAction, &QAction::triggered, this, &SpaceTray::quit);
|
|
m_trayIcon->setContextMenu(m_trayMenu);
|
|
|
|
connect(m_trayIcon, &QSystemTrayIcon::activated, [this](QSystemTrayIcon::ActivationReason reason) {
|
|
if (reason == QSystemTrayIcon::Trigger) {
|
|
fetchData();
|
|
}
|
|
});
|
|
|
|
// Setup network manager
|
|
m_networkManager = new QNetworkAccessManager(this);
|
|
|
|
// Setup timer (300 seconds as per previous delay=300 in C code)
|
|
m_timer = new QTimer(this);
|
|
connect(m_timer, &QTimer::timeout, this, &SpaceTray::fetchData);
|
|
m_timer->start(300000); // 300 seconds in ms
|
|
|
|
// Initial fetch
|
|
fetchData();
|
|
}
|
|
|
|
SpaceTray::~SpaceTray()
|
|
{
|
|
delete m_trayMenu;
|
|
}
|
|
|
|
void SpaceTray::fetchData()
|
|
{
|
|
QNetworkRequest request(m_statusUrl);
|
|
request.setHeader(QNetworkRequest::UserAgentHeader, "Spacetray/0.42 (Qt)");
|
|
request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
|
|
QNetworkReply *reply = m_networkManager->get(request);
|
|
connect(reply, &QNetworkReply::finished, this, [this, reply]() { onFinished(reply); });
|
|
}
|
|
|
|
void SpaceTray::onFinished(QNetworkReply *reply)
|
|
{
|
|
if (reply->error() != QNetworkReply::NoError) {
|
|
qWarning() << "Network error:" << reply->errorString();
|
|
reply->deleteLater();
|
|
return;
|
|
}
|
|
|
|
QByteArray data = reply->readAll();
|
|
reply->deleteLater();
|
|
|
|
// Remove UTF-8 BOM if present
|
|
if (data.startsWith("\xEF\xBB\xBF")) {
|
|
data.remove(0, 3);
|
|
}
|
|
|
|
QJsonParseError error;
|
|
QJsonDocument doc = QJsonDocument::fromJson(data, &error);
|
|
if (doc.isNull()) {
|
|
qWarning() << "Failed to parse JSON:" << error.errorString();
|
|
qWarning() << "Raw data:" << data;
|
|
return;
|
|
}
|
|
|
|
QJsonObject obj = doc.object();
|
|
m_spaceName = obj.value("space").toString("Unknown Space");
|
|
|
|
QJsonObject stateObj = obj.value("state").toObject();
|
|
m_oldDoorOpen = m_doorOpen;
|
|
m_doorOpen = stateObj.value("open").toBool();
|
|
m_doorLastChange = stateObj.value("lastchange").toVariant().toLongLong();
|
|
|
|
updateTray();
|
|
|
|
if (!m_firstRun && m_doorOpen != m_oldDoorOpen) {
|
|
QString dateStr = QDateTime::fromSecsSinceEpoch(m_doorLastChange).toString("yyyy-MM-dd HH:mm:ss");
|
|
QString status = m_doorOpen ? "open" : "closed";
|
|
showNotification(QString("%1: Door %2 since %3").arg(m_spaceName, status, dateStr));
|
|
}
|
|
m_firstRun = false;
|
|
}
|
|
|
|
void SpaceTray::updateTray()
|
|
{
|
|
m_trayIcon->setIcon(m_doorOpen ? m_iconOpen : m_iconClosed);
|
|
|
|
QString dateStr = QDateTime::fromSecsSinceEpoch(m_doorLastChange).toString("yyyy-MM-dd HH:mm:ss");
|
|
QString status = m_doorOpen ? "open" : "closed";
|
|
QString tooltip = QString("%1: Door %2 since %3").arg(m_spaceName, status, dateStr);
|
|
m_trayIcon->setToolTip(tooltip);
|
|
}
|
|
|
|
void SpaceTray::showNotification(const QString &message)
|
|
{
|
|
m_trayIcon->showMessage("SpaceAPI widget for UNIX", message, m_doorOpen ? m_iconOpen : m_iconClosed);
|
|
}
|
|
|
|
void SpaceTray::quit()
|
|
{
|
|
QCoreApplication::quit();
|
|
}
|