From 8c7636f737c3e17695647efb0bd12044d33b42ae Mon Sep 17 00:00:00 2001 From: Skycoder42 Date: Fri, 4 Aug 2017 18:51:21 +0200 Subject: [PATCH] share ccnet --- plugin/fileviewseafileplugin.cpp | 48 +++++++-- plugin/seafstatus.cpp | 173 ++++++++++++++++++++----------- plugin/seafstatus.h | 22 ++-- seafile-test/seafile-test.pro | 6 +- 4 files changed, 172 insertions(+), 77 deletions(-) diff --git a/plugin/fileviewseafileplugin.cpp b/plugin/fileviewseafileplugin.cpp index e75e008..143934d 100644 --- a/plugin/fileviewseafileplugin.cpp +++ b/plugin/fileviewseafileplugin.cpp @@ -2,6 +2,7 @@ #include #include +#include #include @@ -23,8 +24,12 @@ bool FileViewSeafilePlugin::beginRetrieval(const QString &directory) { Q_UNUSED(directory) try { - _seaf->connectCcnet(); - return true; + _seaf->engage(); + _seaf->reloadRepos(); + if(_seaf->hasRepo(directory)) + return true; + else + return false; } catch(QException &e) { emit errorMessage(QString::fromUtf8(e.what())); return false; @@ -33,7 +38,7 @@ bool FileViewSeafilePlugin::beginRetrieval(const QString &directory) void FileViewSeafilePlugin::endRetrieval() { - _seaf->disconnectCcnet(); + _seaf->disengage(); } KVersionControlPlugin::ItemVersion FileViewSeafilePlugin::itemVersion(const KFileItem &item) const @@ -74,10 +79,39 @@ KVersionControlPlugin::ItemVersion FileViewSeafilePlugin::itemVersion(const KFil QList FileViewSeafilePlugin::actions(const KFileItemList &items) const { - Q_UNUSED(items); - return { - new QAction("Test Action", (QObject*)this) - }; +// //test if this it's actually seafile +// try { +// _seaf->reloadRepos(); +// auto itemValid = false; +// foreach(auto item, items) { +// if(_seaf->hasRepo(item.localPath())) +// itemValid = true; +// } +// if(!itemValid) +// return {}; +// } catch(QException &e) { +// qCritical() << e.what(); +// return {}; +// } + +// auto action = new QAction(tr("Seafile"), (QObject*)this); + +// auto menu = new QMenu(); +// action->setMenu(menu); +// connect(action, &QAction::destroyed, +// menu, &QMenu::deleteLater); + +// menu->addAction(QIcon::fromTheme(QStringLiteral("filename-ignore-amarok")), +// tr("Ignore File(s)/Dir(s)")); +// menu->addSeparator(); +// menu->addAction(QIcon::fromTheme(QStringLiteral("view-statistics")), +// tr("Show Quota")); + +// return { +// action +// }; + Q_UNUSED(items) + return {}; } #include "fileviewseafileplugin.moc" diff --git a/plugin/seafstatus.cpp b/plugin/seafstatus.cpp index ff7ee91..e09c504 100644 --- a/plugin/seafstatus.cpp +++ b/plugin/seafstatus.cpp @@ -1,4 +1,5 @@ #include "seafstatus.h" +#include #include #include extern "C" { @@ -6,6 +7,24 @@ extern "C" { #include } +struct CCnetHelper +{ + inline CCnetHelper() : + _pool(ccnet_client_pool_new(nullptr, DEFAULT_CONFIG_DIR)) + {} + inline ~CCnetHelper() { + free(_pool); + } + + inline CcnetClientPool *clientPool() const { + return _pool; + } + +private: + CcnetClientPool *_pool; +}; +Q_GLOBAL_STATIC(CCnetHelper, ccnet) + static QHash path_status = { {"none", SeafStatus::None}, {"syncing", SeafStatus::Syncing}, @@ -20,105 +39,134 @@ static QHash path_status = { SeafStatus::SeafStatus(QObject *parent) : QObject(parent), - _pool(nullptr), _client(nullptr), - _repoIds() -{} + _repoIds(), + _conTimer(new QTimer(this)) +{ + _conTimer->setTimerType(Qt::VeryCoarseTimer); + _conTimer->setInterval(60 * 1000);//1 minute + + connect(_conTimer, &QTimer::timeout, + this, &SeafStatus::freeConnection); +} SeafStatus::~SeafStatus() { - disconnectCcnet(); + freeConnection(); } -void SeafStatus::connectCcnet() +void SeafStatus::engage() { - if(!_pool) - _pool = ccnet_client_pool_new(nullptr, DEFAULT_CONFIG_DIR); - if(!_client && _pool) - _client = ccnet_create_pooled_rpc_client(_pool, nullptr, "seafile-rpcserver"); - - if(!_client) - throw SeafException(0, "Unable to create ccnet rpc client for seafile-rpcserver"); + ensureConnected(); + _conTimer->stop(); +} - loadRepos(); +void SeafStatus::disengage() +{ + _conTimer->start(); } -void SeafStatus::disconnectCcnet() +void SeafStatus::reloadRepos() { + ensureConnected(); _repoIds.clear(); - if(_client){ - ccnet_rpc_client_free(_client); - _client = nullptr; + GError *error = NULL; + auto res = seafile_get_repo_list(_client, 0, -1, &error); + if(error) + throw SeafException(error); + else { + for (auto l = res; l != NULL; l = l->next) { + auto repo = SEAFILE_REPO(l->data); + _repoIds.insert(QString::fromUtf8(seafile_repo_get_worktree(repo)), + QUuid(seafile_repo_get_id(repo))); + } } + g_list_free(res); +} - if(_pool) { - free(_pool); - _pool = nullptr; - } +bool SeafStatus::hasRepo(const QString &path) +{ + return _repoIds.contains(repoPath(path)); } SeafStatus::SyncStatus SeafStatus::syncStatus(const QString &path) { + ensureConnected(); //TODO handle repository folder name - QFileInfo info(path); - auto fullPath = QDir::cleanPath(info.absoluteFilePath()); - foreach (auto repo, _repoIds.keys()) { - if(fullPath.startsWith(repo)) { - QDir repoDir(repo); - auto id = _repoIds[repo]; - auto idString = id.toByteArray(); - idString = idString.mid(1, idString.size() - 2); - - GError *error = NULL; - auto res = searpc_client_call__string(_client, "seafile_get_path_sync_status", &error, 3, - "string", idString.constData(), - "string", repoDir.relativeFilePath(path).toUtf8().constData(), - "int", info.isDir()); - if(error) - throw SeafException(error); - else { - auto status = path_status.value(res); - free(res); - return status; - } + auto repo = repoPath(path); + if(!repo.isNull()) { + QDir repoDir(repo); + auto id = _repoIds[repo]; + auto idString = id.toByteArray(); + idString = idString.mid(1, idString.size() - 2); + + GError *error = NULL; + auto res = searpc_client_call__string(_client, "seafile_get_path_sync_status", &error, 3, + "string", idString.constData(), + "string", repoDir.relativeFilePath(path).toUtf8().constData(), + "int", QFileInfo(path).isDir()); + if(error) + throw SeafException(error); + else { + auto status = path_status.value(res); + free(res); + return status; } } return None; } -void SeafStatus::loadRepos() +void SeafStatus::ensureConnected() { - _repoIds.clear(); + if(!_client) { + auto pool = ccnet->clientPool(); + if(!pool) + throw SeafException(tr("Ccnet pool unavailable - make shure ccnet is running")); - GError *error = NULL; - auto res = seafile_get_repo_list(_client, 0, -1, &error); - if(error) - throw SeafException(error); - else { - for (auto l = res; l != NULL; l = l->next) { - auto repo = SEAFILE_REPO(l->data); - _repoIds.insert(QString::fromUtf8(repo->_worktree), - QUuid(repo->_id)); - } + _client = ccnet_create_pooled_rpc_client(pool, nullptr, "seafile-rpcserver"); + if(!_client) + throw SeafException(tr("Unable to create ccnet rpc client for seafile-rpcserver")); + + reloadRepos(); } - g_list_free(res); + + _conTimer->start(); +} + +void SeafStatus::freeConnection() +{ + if(_client){ + ccnet_rpc_client_free(_client); + _client = nullptr; + } +} + +QString SeafStatus::repoPath(const QString &path) +{ + QFileInfo info(path); + auto fullPath = QDir::cleanPath(info.absoluteFilePath()); + foreach (auto repo, _repoIds.keys()) { + if(fullPath.startsWith(repo)) + return repo; + } + + return QString(); } SeafException::SeafException(GError *error) : - SeafException(error->code, error->message) + SeafException(SeafStatus::tr("Seafile Extension: %1").arg(QString::fromUtf8(error->message)).toUtf8()) { g_free(error); } -SeafException::SeafException(int code, QByteArray message) : +SeafException::SeafException(QString message) : QException(), - _code(code), - _message(message) + _message(SeafStatus::tr("Seafile Extension: %1").arg(message).toUtf8()) {} const char *SeafException::what() const noexcept @@ -133,5 +181,10 @@ void SeafException::raise() const QException *SeafException::clone() const { - return new SeafException(_code, _message); + return new SeafException(_message); } + +SeafException::SeafException(QByteArray message) : + QException(), + _message(message) +{} diff --git a/plugin/seafstatus.h b/plugin/seafstatus.h index d36d292..bd5aaa8 100644 --- a/plugin/seafstatus.h +++ b/plugin/seafstatus.h @@ -5,6 +5,7 @@ #include #include #include +#include extern "C" { #include } @@ -13,7 +14,7 @@ class SeafException : public QException { public: SeafException(GError *error); - SeafException(int code, QByteArray message); + SeafException(QString message); const char *what() const noexcept override; @@ -22,7 +23,8 @@ class SeafException : public QException QException *clone() const override; private: - int _code; + SeafException(QByteArray message); + QByteArray _message; }; @@ -48,18 +50,24 @@ class SeafStatus : public QObject explicit SeafStatus(QObject *parent = nullptr); ~SeafStatus(); - void connectCcnet(); - void disconnectCcnet(); + void engage(); + void disengage(); + + void reloadRepos(); + bool hasRepo(const QString &path); SyncStatus syncStatus(const QString &path); +private slots: + void ensureConnected(); + void freeConnection(); + private: - CcnetClientPool *_pool; SearpcClient *_client; - QHash _repoIds; + QTimer *_conTimer; - void loadRepos(); + QString repoPath(const QString &path); }; #endif // SEAFSTATUS_H diff --git a/seafile-test/seafile-test.pro b/seafile-test/seafile-test.pro index 9ca886c..7e87937 100644 --- a/seafile-test/seafile-test.pro +++ b/seafile-test/seafile-test.pro @@ -11,7 +11,7 @@ TEMPLATE = app SOURCES += \ main.cpp \ - seafstatus.cpp + seafstatus.cpp # The following define makes your compiler emit warnings if you use # any feature of Qt which as been marked deprecated (the exact warnings @@ -28,5 +28,5 @@ CONFIG += link_pkgconfig PKGCONFIG += libseafile libccnet HEADERS += \ - ../../../../../usr/include/seafile/seafile-rpc.h \ - seafstatus.h + /usr/include/seafile/seafile-rpc.h \ + seafstatus.h