Skip to content
This repository has been archived by the owner on Mar 4, 2023. It is now read-only.

Commit

Permalink
share ccnet
Browse files Browse the repository at this point in the history
  • Loading branch information
Skycoder42 committed Aug 4, 2017
1 parent a78081c commit 8c7636f
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 77 deletions.
48 changes: 41 additions & 7 deletions plugin/fileviewseafileplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <KPluginFactory>
#include <KFileItem>
#include <QMenu>

#include <QDebug>

Expand All @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -74,10 +79,39 @@ KVersionControlPlugin::ItemVersion FileViewSeafilePlugin::itemVersion(const KFil

QList<QAction *> 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"
173 changes: 113 additions & 60 deletions plugin/seafstatus.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
#include "seafstatus.h"
#include <QGlobalStatic>
#include <QDebug>
#include <QDir>
extern "C" {
#include <seafile/seafile-object.h>
#include <seafile/seafile.h>
}

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<QByteArray, SeafStatus::SyncStatus> path_status = {
{"none", SeafStatus::None},
{"syncing", SeafStatus::Syncing},
Expand All @@ -20,105 +39,134 @@ static QHash<QByteArray, SeafStatus::SyncStatus> 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
Expand All @@ -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)
{}
22 changes: 15 additions & 7 deletions plugin/seafstatus.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <QHash>
#include <QUuid>
#include <QException>
#include <QTimer>
extern "C" {
#include <ccnet.h>
}
Expand All @@ -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;

Expand All @@ -22,7 +23,8 @@ class SeafException : public QException
QException *clone() const override;

private:
int _code;
SeafException(QByteArray message);

QByteArray _message;
};

Expand All @@ -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<QString, QUuid> _repoIds;
QTimer *_conTimer;

void loadRepos();
QString repoPath(const QString &path);
};

#endif // SEAFSTATUS_H
6 changes: 3 additions & 3 deletions seafile-test/seafile-test.pro
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

0 comments on commit 8c7636f

Please sign in to comment.