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

Commit

Permalink
update seafstatus to work with latest seafile
Browse files Browse the repository at this point in the history
  • Loading branch information
Skycoder42 committed Nov 5, 2019
1 parent e6c7a41 commit 4c59fe9
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 74 deletions.
181 changes: 109 additions & 72 deletions plugin/seafstatus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,65 @@
#include <QDir>
#include <QFile>
#include <QTextStream>
#include <chrono>

extern "C" {
#include <searpc-named-pipe-transport.h>
#include <searpc.h>
#include <seafile/seafile-object.h>
#include <seafile/seafile.h>
#include <seafile/seafile-error.h>
}

namespace {

struct ScopedPointerGErrorDeleter
{
static inline void cleanup(GError *err) {
if (err)
g_error_free(err);
}
};

struct ScopedPointerGListDeleter
{
static inline void cleanup(GList *list) {
if (list)
g_list_free(list);
}
};

struct ScopedPointerGObjectDeleter
{
static inline void cleanup(GObject *obj) {
if (obj)
g_object_unref(obj);
}
};

struct ScopedPointerGStringDeleter
{
static inline void cleanup(char *str) {
if (str)
free(str);
}
};

using GListPtr = QScopedPointer<GList, ScopedPointerGListDeleter>;
using GErrorPtr = QScopedPointer<GError, ScopedPointerGErrorDeleter>;
using GObjectPtr = QScopedPointer<GObject, ScopedPointerGObjectDeleter>;
using GStringPtr = QScopedPointer<char, ScopedPointerGStringDeleter>;

}

using namespace std::chrono_literals;

SeafStatus::SeafStatus(QObject *parent) :
QObject(parent),
_client(nullptr),
_repoIds(),
_conTimer(new QTimer(this))
QObject{parent},
_conTimer{new QTimer(this)}
{
_conTimer->setTimerType(Qt::VeryCoarseTimer);
_conTimer->setInterval(60 * 1000);//1 minute

_conTimer->setInterval(1min);
connect(_conTimer, &QTimer::timeout,
this, &SeafStatus::freeConnection);
}
Expand All @@ -45,26 +87,25 @@ void SeafStatus::reloadRepos()
ensureConnected();
_repoIds.clear();

GError *error = nullptr;
auto res = seafile_get_repo_list(_client, 0, -1, &error);
if(error)
throw SeafException(error);
else {
for (auto l = res; l != nullptr; l = l->next) {
auto repo = SEAFILE_REPO(l->data);
_repoIds.insert(QString::fromUtf8(seafile_repo_get_worktree(repo)),
QUuid(seafile_repo_get_id(repo)));
}
GError *rawError = nullptr;
GListPtr res {seafile_get_repo_list(_client, 0, -1, &rawError)};
GErrorPtr error{rawError};
if (error)
throw SeafException(error.data());

for (auto l = res.data(); l != nullptr; 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);
}

bool SeafStatus::hasRepo(const QString &path) const
{
return _repoIds.contains(repoPath(path));
}

QStringList SeafStatus::allRepost() const
QStringList SeafStatus::allRepos() const
{
return _repoIds.keys();
}
Expand All @@ -74,45 +115,44 @@ SeafStatus::SyncStatus SeafStatus::syncStatus(const QString &path)
ensureConnected();

auto repo = repoPath(path);
if(!repo.isNull()) {
if (!repo.isNull()) {
QDir repoDir{repo};
auto id = _repoIds.value(repo);
auto idString = id.toByteArray();
idString = idString.mid(1, idString.size() - 2);

if(repo == path) {
GError *error = nullptr;
auto taskObj = searpc_client_call__object (_client, "seafile_get_repo_sync_task", SEAFILE_TYPE_SYNC_TASK,
&error, 1,
"string", idString.constData());
auto task = SEAFILE_SYNC_TASK(taskObj);
if(error)
throw SeafException(error);
else {
if(QByteArray{seafile_sync_task_get_error(task)} != "Success") {
auto msg = QString::fromUtf8(seafile_sync_task_get_err_detail(task));
g_object_unref(taskObj);
throw SeafException{std::move(msg)};
} else {
auto status = mapRepoStatus(seafile_sync_task_get_state(task));
g_object_unref(taskObj);
return status;
}
}
const auto id = _repoIds.value(repo);
const auto idString = id.toByteArray(QUuid::WithoutBraces);

if (repo == path) {
GError *rawError = nullptr;
GObjectPtr taskObj{searpc_client_call__object(_client, "seafile_get_repo_sync_task", SEAFILE_TYPE_SYNC_TASK,
&rawError, 1,
"string", idString.constData())};
GErrorPtr error{rawError};
auto task = SEAFILE_SYNC_TASK(taskObj.data());
if (error)
throw SeafException(error.data());

const auto syncErr = seafile_sync_task_get_error(task);
if (syncErr != SYNC_ERROR_ID_NO_ERROR) {
GStringPtr errStr{searpc_client_call__string(_client, "seafile_sync_error_id_to_str",
&rawError, 1,
"int", syncErr)};
error.reset(rawError);
if (error)
throw SeafException(error.data());
throw SeafException{QString::fromUtf8(errStr.data())};
} else
return mapRepoStatus(seafile_sync_task_get_state(task));
} else {
GError *error = nullptr;
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 = mapFileStatus(res);
free(res);
return status;
}
GError *rawError = nullptr;
GStringPtr res{searpc_client_call__string(_client, "seafile_get_path_sync_status",
&rawError, 3,
"string", idString.constData(),
"string", repoDir.relativeFilePath(path).toUtf8().constData(),
"int", QFileInfo{path}.isDir())};
GErrorPtr error{rawError};
if (error)
throw SeafException(error.data());

return mapFileStatus(res.data());
}
}

Expand All @@ -121,21 +161,20 @@ SeafStatus::SyncStatus SeafStatus::syncStatus(const QString &path)

void SeafStatus::ensureConnected()
{
if(!_client) {
if (!_client) {
// find the socket
auto seafDir = readSeafileIni();
if(seafDir.isNull())
if (seafDir.isNull())
seafDir = QDir::home().filePath(QStringLiteral("Seafile/.seafile-data"));
auto path = QDir{seafDir}.absoluteFilePath(QStringLiteral("seafile.sock"));
const auto path = QDir{seafDir}.absoluteFilePath(QStringLiteral("seafile.sock"));

// create the client
auto pipe_client = searpc_create_named_pipe_client(qUtf8Printable(path));
int ret = searpc_named_pipe_client_connect(pipe_client);
_client = searpc_client_with_named_pipe_transport(pipe_client, "seafile-rpcserver");
if (ret < 0) {
searpc_free_client_with_pipe_transport(_client);
_client = nullptr;
throw SeafException(tr("Unable to create piped searpc client for seafile-rpcserver"));
freeConnection();
throw SeafException(tr("Unable to create piped searpc client for seafile-rpcserver"));
}

reloadRepos();
Expand All @@ -154,16 +193,16 @@ void SeafStatus::freeConnection()

QString SeafStatus::repoPath(const QString &path) const
{
QFileInfo info(path);
auto fullPath = QDir::cleanPath(info.absoluteFilePath());
const QFileInfo info{path};
const auto fullPath = QDir::cleanPath(info.absoluteFilePath());
for(auto it = _repoIds.constBegin(); it != _repoIds.constEnd(); it++) {
if(fullPath.startsWith(it.key()))
if (fullPath.startsWith(it.key()))
return it.key();
else if(QFileInfo{it.key()}.dir() == QDir{path})
return it.key();
}

return QString();
return {};
}

SeafStatus::SyncStatus SeafStatus::mapFileStatus(const QByteArray &text) const
Expand Down Expand Up @@ -204,23 +243,23 @@ QString SeafStatus::readSeafileIni() const
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
auto env = qEnvironmentVariable("SEAFILE_DATA_DIR");
if(!env.isNull())
if (!env.isNull())
return env;
auto ccnetDir = qEnvironmentVariable("CCNET_CONF_DIR");
#else
auto env = qgetenv("SEAFILE_DATA_DIR");
if(!env.isNull())
if (!env.isNull())
return QString::fromUtf8(env);
auto ccnetDir = QString::fromUtf8(qgetenv("CCNET_CONF_DIR"));
#endif
if(ccnetDir.isNull())
if (ccnetDir.isNull())
ccnetDir = QDir::home().filePath(QStringLiteral(".ccnet"));

QFile seafile_ini(QDir{ccnetDir}.filePath(QStringLiteral("seafile.ini")));
if (!seafile_ini.exists())
return {};

if(!seafile_ini.open(QIODevice::ReadOnly | QIODevice::Text))
if (!seafile_ini.open(QIODevice::ReadOnly | QIODevice::Text))
throw SeafException(tr("%1: %2").arg(seafile_ini.fileName(), seafile_ini.errorString()));

QTextStream input(&seafile_ini);
Expand All @@ -235,9 +274,7 @@ QString SeafStatus::readSeafileIni() const

SeafException::SeafException(GError *error) :
SeafException(SeafStatus::tr("Seafile Extension: %1").arg(QString::fromUtf8(error->message)).toUtf8())
{
g_error_free(error);
}
{}

SeafException::SeafException(const QString &message) :
QException(),
Expand Down
4 changes: 2 additions & 2 deletions plugin/seafstatus.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,15 @@ class SeafStatus : public QObject
void reloadRepos();

bool hasRepo(const QString &path) const;
QStringList allRepost() const;
QStringList allRepos() const;
SyncStatus syncStatus(const QString &path);

private slots:
void ensureConnected();
void freeConnection();

private:
SearpcClient *_client;
SearpcClient *_client = nullptr;
QHash<QString, QUuid> _repoIds;
QTimer *_conTimer;

Expand Down

0 comments on commit 4c59fe9

Please sign in to comment.