#ifndef WITH_KF5 //TODO: actually it makes no sense to have overlayplugin without KF5, since it seems to be available only after >= 5.16 #include #include #include #else #include #include #include //#include #endif #include #include #include #include #if QT_VERSION >= 0x050000 #include #endif typedef enum { FILE_ERROR = 0, FILE_SYNCED = 1, FILE_PENDING = 2, FILE_SYNCING = 3, FILE_NOTFOUND = 9, } FileState; const char OP_PATH_STATE = 'P'; //Path state const char OP_INIT = 'I'; //Init operation const char OP_END = 'E'; //End operation const char OP_UPLOAD = 'F'; //File-Folder upload const char OP_LINK = 'L'; //paste Link const char OP_SHARE = 'S'; //Share folder const char OP_SEND = 'C'; //Copy to user const char OP_STRING = 'T'; //Get Translated String const char OP_VIEW = 'V'; //View on MEGA const char OP_PREVIOUS = 'R'; //View previous versions class MegasyncDolphinOverlayPlugin : public KOverlayIconPlugin { Q_PLUGIN_METADATA(IID "com.megasync.ovarlayiconplugin" FILE "megasync-plugin-overlay.json") Q_OBJECT typedef QHash StatusMap; StatusMap m_status; QLocalSocket sockNotifyServer; QString sockPathNofityServer; QLocalSocket sockExtServer; QString sockPathExtServer; private slots: void sockNotifyServer_connected() { qDebug("MEGASYNCOVERLAYPLUGIN: connected to Notify Server"); } void sockNotifyServer_disconnected() { qDebug("MEGASYNCOVERLAYPLUGIN: disconnected from Notify Server"); } void sockNotifyServer_error(QLocalSocket::LocalSocketError err) { QMetaEnum metaEnum = QMetaEnum::fromType(); qCritical("MEGASYNCOVERLAYPLUGIN: error in connection to notify server: %s", metaEnum.valueToKey(err)); } void sockExtServer_connected() { qDebug("MEGASYNCOVERLAYPLUGIN: connected to Ext Server"); } void sockExtServer_disconnected() { qDebug("MEGASYNCOVERLAYPLUGIN: disconnected from Ext Server"); } void sockExtServer_error(QLocalSocket::LocalSocketError err) { QMetaEnum metaEnum = QMetaEnum::fromType(); qCritical("MEGASYNCOVERLAYPLUGIN: error in connection to ext server: %s", metaEnum.valueToKey(err)); } void notifiedfromServer() { qDebug("MEGASYNCOVERLAYPLUGIN: notifiedfromServer"); while(sockNotifyServer.canReadLine()) { char type[1]; sockNotifyServer.read(type, 1); //TODO: control errors QString action="unknown"; switch(*type) { case 'P': // item state changed action="item state changed"; break; case 'A': // sync folder added action="sync folder added"; break; case 'D': // sync folder deleted action="sync folder deleted"; break; default: qCritical("MEGASYNCOVERLAYPLUGIN: unexpected read from notifyServer. type=%s", type); break; } QString url = sockNotifyServer.readLine(); while(url.endsWith('\n')) url.chop(1); qDebug("MEGASYNCOVERLAYPLUGIN: Server notified <%s>: %s",action.toUtf8().constData(), url.toUtf8().constData()); emit overlaysChanged(QUrl::fromLocalFile(url), getOverlays(QUrl::fromLocalFile(url))); } } public: MegasyncDolphinOverlayPlugin() { qDebug("MEGASYNCOVERLAYPLUGIN: Loading plugin ... "); connect(&sockNotifyServer, SIGNAL(connected()), this, SLOT(sockNotifyServer_connected())); connect(&sockNotifyServer, SIGNAL(disconnected()), this, SLOT(sockNotifyServer_disconnected())); connect(&sockNotifyServer, SIGNAL(readyRead()), this, SLOT(notifiedfromServer())); connect(&sockNotifyServer, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(sockNotifyServer_error(QLocalSocket::LocalSocketError))); connect(&sockExtServer, SIGNAL(connected()), this, SLOT(sockExtServer_connected())); connect(&sockExtServer, SIGNAL(disconnected()), this, SLOT(sockExtServer_disconnected())); connect(&sockExtServer, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(sockExtServer_error(QLocalSocket::LocalSocketError))); #if QT_VERSION < 0x050000 sockPathNofityServer = QDir::home().path(); sockPathNofityServer.append(QDir::separator()).append(".local/share/data/Mega Limited/MEGAsync/notify.socket"); #else sockPathNofityServer = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); sockPathNofityServer.append(QDir::separator()).append("data/Mega Limited/MEGAsync/notify.socket"); #endif sockNotifyServer.connectToServer(sockPathNofityServer); #if QT_VERSION < 0x050000 sockPathExtServer = QDir::home().path(); sockPathExtServer.append(QDir::separator()).append(".local/share/data/Mega Limited/MEGAsync/mega.socket"); #else sockPathExtServer = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); sockPathExtServer.append(QDir::separator()).append("data/Mega Limited/MEGAsync/mega.socket"); #endif sockExtServer.connectToServer(sockPathExtServer); } ~MegasyncDolphinOverlayPlugin() { sockNotifyServer.close(); } QStringList getOverlays(const QUrl& url) override { if (!url.isLocalFile()) { return QStringList(); } QStringList r; int state = getState(url.toLocalFile()); switch (state) { case FILE_SYNCED: r << "mega-dolphin-synced"; qDebug("MEGASYNCOVERLAYPLUGIN: getOverlays <%s>: mega-dolphin-synced",url.toLocalFile().toUtf8().constData()); break; case FILE_PENDING: r << "mega-dolphin-pending"; qDebug("MEGASYNCOVERLAYPLUGIN: getOverlays <%s>: mega-dolphin-pending",url.toLocalFile().toUtf8().constData()); break; case FILE_SYNCING: r << "mega-dolphin-syncing"; qDebug("MEGASYNCOVERLAYPLUGIN: getOverlays <%s>: mega-dolphin-syncing",url.toLocalFile().toUtf8().constData()); break; default: qDebug("MEGASYNCOVERLAYPLUGIN: getOverlays <%s>: %d",url.toLocalFile().toUtf8().constData(),state); break; } return r; return QStringList(); } private: int getState(QString path) { QString res; res = sendRequest(OP_PATH_STATE, QFileInfo(path).canonicalFilePath()); return res.toInt(); } // send request and receive response from Extension server // Return newly-allocated response string QString sendRequest(char type, QString command) { int waitTime = -1; // This (instead of a timeout) makes dolphin hang until the location for an upload is selected (will be corrected in megasync>3.0.1). // Otherwise megaync segafaults accesing client socket QString req; if(!sockExtServer.isOpen()) { sockExtServer.connectToServer(sockPathExtServer); if(!sockExtServer.waitForConnected(waitTime)) return QString(); } req.sprintf("%c:%s", type, command.toUtf8().constData()); sockExtServer.write(req.toUtf8()); sockExtServer.flush(); if(!sockExtServer.waitForReadyRead(waitTime)) { sockExtServer.close(); return QString(); } QString reply; reply.append(sockExtServer.readAll()); return reply; } }; #include "megasync-plugin-overlay.moc"