mirror of
https://github.com/nextcloud/desktop.git
synced 2025-10-26 11:17:43 +00:00
Add socketapi
Slightly amended by: Daniel Molkentin <danimo@owncloud.com>
This commit is contained in:
parent
d0af48c417
commit
e304dfd5b9
@ -220,6 +220,7 @@ set(mirall_SRCS
|
||||
mirall/ignorelisteditor.cpp
|
||||
mirall/itemprogressdialog.cpp
|
||||
mirall/owncloudgui.cpp
|
||||
mirall/socketapi.cpp
|
||||
)
|
||||
|
||||
set(mirall_HEADERS
|
||||
@ -245,6 +246,7 @@ set(mirall_HEADERS
|
||||
mirall/ignorelisteditor.h
|
||||
mirall/itemprogressdialog.h
|
||||
mirall/owncloudgui.h
|
||||
mirall/socketapi.h
|
||||
)
|
||||
|
||||
if( UNIX AND NOT APPLE)
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
#include "mirall/logger.h"
|
||||
#include "mirall/utility.h"
|
||||
#include "mirall/connectionvalidator.h"
|
||||
#include "mirall/socketapi.h"
|
||||
|
||||
#include "creds/abstractcredentials.h"
|
||||
|
||||
@ -146,6 +147,9 @@ Application::Application(int &argc, char **argv) :
|
||||
connect (this, SIGNAL(aboutToQuit()), SLOT(slotCleanup()));
|
||||
|
||||
qDebug() << "Network Location: " << NetworkLocation::currentLocation().encoded();
|
||||
|
||||
|
||||
_socketApi = new SocketApi(this, cfg.configPathWithAppName().append(QLatin1String("socket")));
|
||||
}
|
||||
|
||||
Application::~Application()
|
||||
@ -159,7 +163,6 @@ void Application::slotCleanup()
|
||||
// that saving the geometries happens ASAP during a OS shutdown
|
||||
_gui->slotShutdown();
|
||||
_gui->deleteLater();
|
||||
|
||||
}
|
||||
|
||||
void Application::slotStartUpdateDetector()
|
||||
|
||||
@ -44,6 +44,7 @@ class ownCloudInfo;
|
||||
class SslErrorDialog;
|
||||
class SettingsDialog;
|
||||
class ItemProgressDialog;
|
||||
class SocketApi;
|
||||
|
||||
class Application : public SharedTools::QtSingleApplication
|
||||
{
|
||||
@ -91,6 +92,7 @@ private:
|
||||
void runValidator();
|
||||
|
||||
QPointer<ownCloudGui> _gui;
|
||||
QPointer<SocketApi> _socketApi;
|
||||
// QNetworkConfigurationManager *_networkMgr;
|
||||
|
||||
SslErrorDialog *_sslErrorDialog;
|
||||
|
||||
@ -429,6 +429,23 @@ void FolderMan::addFolderDefinition(const QString& alias, const QString& sourceF
|
||||
settings.sync();
|
||||
}
|
||||
|
||||
Folder *FolderMan::folderForPath(const QUrl &path)
|
||||
{
|
||||
QString absolutePath = path.toLocalFile();
|
||||
absolutePath.append("/");
|
||||
|
||||
foreach(Folder* folder, map().values())
|
||||
{
|
||||
if(absolutePath.startsWith(folder->path()))
|
||||
{
|
||||
qDebug() << "found folder: " << folder->path() << " for " << absolutePath;
|
||||
return folder;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FolderMan::removeAllFolderDefinitions()
|
||||
{
|
||||
foreach( Folder *f, _folderMap.values() ) {
|
||||
|
||||
@ -50,6 +50,9 @@ public:
|
||||
*/
|
||||
void addFolderDefinition(const QString&, const QString&, const QString& );
|
||||
|
||||
/** Returns the folder which the file or directory stored in path is in */
|
||||
Folder* folderForPath(const QUrl& path);
|
||||
|
||||
/** Returns the folder by alias or NULL if no folder with the alias exists. */
|
||||
Folder *folder( const QString& );
|
||||
|
||||
|
||||
@ -170,6 +170,12 @@ QString MirallConfigFile::configPath() const
|
||||
return dir;
|
||||
}
|
||||
|
||||
QString MirallConfigFile::configPathWithAppName() const
|
||||
{
|
||||
//HACK
|
||||
return QFileInfo( configFile() ).dir().absolutePath().append("/");
|
||||
}
|
||||
|
||||
QString MirallConfigFile::excludeFile(Scope scope) const
|
||||
{
|
||||
// prefer sync-exclude.lst, but if it does not exist, check for
|
||||
|
||||
@ -33,6 +33,7 @@ public:
|
||||
enum Scope { UserScope, SystemScope };
|
||||
|
||||
QString configPath() const;
|
||||
QString configPathWithAppName() const;
|
||||
QString configFile() const;
|
||||
QString excludeFile(Scope scope) const;
|
||||
|
||||
|
||||
198
src/mirall/socketapi.cpp
Normal file
198
src/mirall/socketapi.cpp
Normal file
@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright (C) by Dominik Schmidt <dev@dominik-schmidt.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
|
||||
#include "socketapi.h"
|
||||
|
||||
#include "mirall/mirallconfigfile.h"
|
||||
#include "mirall/folderman.h"
|
||||
#include "mirall/folder.h"
|
||||
#include "mirall/utility.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QUrl>
|
||||
#include <QLocalSocket>
|
||||
#include <QLocalServer>
|
||||
#include <QMetaObject>
|
||||
#include <QStringList>
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
#include <QApplication>
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
#define DEBUG qDebug() << "SocketApi: "
|
||||
|
||||
SocketApi::SocketApi(QObject* parent, const QUrl& localFile)
|
||||
: QObject(parent)
|
||||
, _localServer(0)
|
||||
{
|
||||
QString socketPath = localFile.toLocalFile();
|
||||
DEBUG << "ctor: " << socketPath;
|
||||
|
||||
// setup socket
|
||||
_localServer = new QLocalServer(this);
|
||||
QLocalServer::removeServer(socketPath);
|
||||
if(!_localServer->listen(socketPath))
|
||||
DEBUG << "can't start server";
|
||||
else
|
||||
DEBUG << "server started";
|
||||
connect(_localServer, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
|
||||
|
||||
// folder watcher
|
||||
connect(FolderMan::instance(), SIGNAL(folderSyncStateChange(QString)), SLOT(onSyncStateChanged(QString)));
|
||||
}
|
||||
|
||||
SocketApi::~SocketApi()
|
||||
{
|
||||
DEBUG << "dtor";
|
||||
_localServer->close();
|
||||
}
|
||||
|
||||
void SocketApi::onNewConnection()
|
||||
{
|
||||
QLocalSocket* socket = _localServer->nextPendingConnection();
|
||||
DEBUG << "New connection " << socket;
|
||||
connect(socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
|
||||
connect(socket, SIGNAL(disconnected()), this, SLOT(onLostConnection()));
|
||||
Q_ASSERT(socket->readAll().isEmpty());
|
||||
|
||||
_listeners.append(socket);
|
||||
}
|
||||
|
||||
void SocketApi::onLostConnection()
|
||||
{
|
||||
DEBUG << "Lost connection " << sender();
|
||||
|
||||
QLocalSocket* socket = qobject_cast< QLocalSocket* >(sender());
|
||||
_listeners.removeAll(socket);
|
||||
}
|
||||
|
||||
|
||||
void SocketApi::onReadyRead()
|
||||
{
|
||||
QLocalSocket* socket = qobject_cast<QLocalSocket*>(sender());
|
||||
Q_ASSERT(socket);
|
||||
|
||||
while(socket->canReadLine())
|
||||
{
|
||||
QString line = QString::fromUtf8(socket->readLine()).trimmed();
|
||||
QString command = line.split(":").first();
|
||||
QString function = QString(QLatin1String("command_")).append(command);
|
||||
|
||||
QString functionWithArguments = function + QLatin1String("(QString,QLocalSocket*)");
|
||||
int indexOfMethod = this->metaObject()->indexOfMethod(functionWithArguments.toAscii());
|
||||
|
||||
QString argument = line.remove(0, command.length()+1).trimmed();
|
||||
if(indexOfMethod != -1)
|
||||
{
|
||||
QMetaObject::invokeMethod(this, function.toAscii(), Q_ARG(QString, argument), Q_ARG(QLocalSocket*, socket));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG << "The command is not supported by this version of the client:" << command << "with argument:" << argument;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SocketApi::onSyncStateChanged(const QString&)
|
||||
{
|
||||
DEBUG << "Sync state changed";
|
||||
|
||||
broadcastMessage("UPDATE_VIEW");
|
||||
}
|
||||
|
||||
|
||||
void SocketApi::sendMessage(QLocalSocket* socket, const QString& message)
|
||||
{
|
||||
DEBUG << "Sending message: " << message;
|
||||
QString localMessage = message;
|
||||
socket->write(localMessage.append("\n").toUtf8());
|
||||
}
|
||||
|
||||
void SocketApi::broadcastMessage(const QString& message)
|
||||
{
|
||||
DEBUG << "Broadcasting to" << _listeners.count() << "listeners: " << message;
|
||||
foreach(QLocalSocket* current, _listeners)
|
||||
{
|
||||
sendMessage(current, message);
|
||||
}
|
||||
}
|
||||
|
||||
void SocketApi::command_RETRIEVE_FOLDER_STATUS(const QString& argument, QLocalSocket* socket)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << argument;
|
||||
//TODO: do security checks?!
|
||||
Folder* folder = FolderMan::instance()->folderForPath( argument );
|
||||
// this can happen in offline mode e.g.: nothing to worry about
|
||||
if(!folder)
|
||||
{
|
||||
DEBUG << "folder offline or not watched:" << argument;
|
||||
return;
|
||||
}
|
||||
|
||||
QDir dir(argument);
|
||||
foreach(QString entry, dir.entryList(QDir::AllEntries|QDir::NoDotAndDotDot))
|
||||
{
|
||||
QString absoluteFilePath = dir.absoluteFilePath(entry);
|
||||
QString statusString;
|
||||
SyncFileStatus fileStatus = folder->fileStatus(absoluteFilePath.mid(folder->path().length()));
|
||||
switch(fileStatus)
|
||||
{
|
||||
case STATUS_NONE:
|
||||
statusString = QLatin1String("STATUS_NONE");
|
||||
break;
|
||||
case STATUS_EVAL:
|
||||
statusString = QLatin1String("STATUS_EVAL");
|
||||
break;
|
||||
case STATUS_REMOVE:
|
||||
statusString = QLatin1String("STATUS_REMOVE");
|
||||
break;
|
||||
case STATUS_RENAME:
|
||||
statusString = QLatin1String("STATUS_RENAME");
|
||||
break;
|
||||
case STATUS_NEW:
|
||||
statusString = QLatin1String("STATUS_NEW");
|
||||
break;
|
||||
case STATUS_CONFLICT:
|
||||
statusString = QLatin1String("STATUS_CONFLICT");
|
||||
break;
|
||||
case STATUS_IGNORE:
|
||||
statusString = QLatin1String("STATUS_IGNORE");
|
||||
break;
|
||||
case STATUS_SYNC:
|
||||
statusString = QLatin1String("STATUS_SYNC");
|
||||
break;
|
||||
case STATUS_STAT_ERROR:
|
||||
statusString = QLatin1String("STATUS_STAT_ERROR");
|
||||
break;
|
||||
case STATUS_ERROR:
|
||||
statusString = QLatin1String("STATUS_ERROR");
|
||||
break;
|
||||
case STATUS_UPDATED:
|
||||
statusString = QLatin1String("STATUS_UPDATED");
|
||||
break;
|
||||
default:
|
||||
qWarning() << "not all SyncFileStatus items checked!";
|
||||
Q_ASSERT(false);
|
||||
statusString = QLatin1String("STATUS_NONE");
|
||||
|
||||
}
|
||||
QString message("%1:%2:%3");
|
||||
message = message.arg("STATUS").arg(statusString).arg(absoluteFilePath);
|
||||
sendMessage(socket, message);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Mirall
|
||||
54
src/mirall/socketapi.h
Normal file
54
src/mirall/socketapi.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) by Dominik Schmidt <dev@dominik-schmidt.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SOCKETAPI_H
|
||||
#define SOCKETAPI_H
|
||||
|
||||
#include <QWeakPointer>
|
||||
|
||||
class QUrl;
|
||||
class QLocalSocket;
|
||||
class QLocalServer;
|
||||
class QStringList;
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
class SocketApi : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SocketApi(QObject* parent, const QUrl& localFile);
|
||||
virtual ~SocketApi();
|
||||
|
||||
private slots:
|
||||
void onNewConnection();
|
||||
void onLostConnection();
|
||||
void onReadyRead();
|
||||
void onSyncStateChanged(const QString&);
|
||||
|
||||
private:
|
||||
void sendMessage(QLocalSocket* socket, const QString& message);
|
||||
void broadcastMessage(const QString& message);
|
||||
|
||||
Q_INVOKABLE void command_RETRIEVE_FOLDER_STATUS(const QString& argument, QLocalSocket* socket);
|
||||
|
||||
private:
|
||||
QLocalServer* _localServer;
|
||||
QList< QLocalSocket* > _listeners;
|
||||
};
|
||||
|
||||
}
|
||||
#endif // SOCKETAPI_H
|
||||
Loading…
Reference in New Issue
Block a user