clean seafile api

This commit is contained in:
shell committed 2026-07-21 22:00:38 +08:00
1 parent 133424f5f8
commit 3e4694ceb5
14 files changed
+476 -290

No files matched your search

+41 -102
View File
@@ -7,13 +7,11 @@
#include "seafile_api_interface.hpp"
#include "seafile/cache/cache.hpp"
namespace seafile::api
{
class CachedSeafileApi final : public ISeaFileApi
{
namespace seafile::api {
class CachedSeafileApi final : public ISeaFileApi {
mutable cache::Cache<std::string, FileInfo> file_info_cache;
mutable cache::Cache<std::string, DirInfo> dir_info_cache;
mutable cache::Cache<std::string, std::vector<RepoEntry>> repo_entries_cache;
mutable cache::Cache<std::string, std::vector<RepoEntry> > repo_entries_cache;
mutable cache::Cache<std::string, AccountInfo> account_info_cache;
std::shared_ptr<ISeaFileApi> underlayer_api;
@@ -22,13 +20,11 @@ namespace seafile::api
static std::string makeKey(
std::string_view prefix,
std::initializer_list<std::string_view> args
)
{
) {
std::string key(prefix);
for (auto& arg : args)
{
key += ":";
for (auto &arg: args) {
key += ':';
key += arg;
}
@@ -36,66 +32,46 @@ namespace seafile::api
}
public:
explicit CachedSeafileApi(std::shared_ptr<ISeaFileApi> api) : underlayer_api(std::move(api))
{
explicit CachedSeafileApi(std::shared_ptr<ISeaFileApi> api) : underlayer_api(std::move(api)) {
};
tl::expected<AuthToken, SeafileException>
authToken(
const std::string& username,
const std::string& password
) override
{
return underlayer_api->authToken(username, password);
auth(
const std::string &username,
const std::string &password
) override {
return underlayer_api->auth(username, password);
}
tl::expected<ServerInfo, SeafileException>
serverInfo() const override
{
serverInfo() const override {
return underlayer_api->serverInfo();
}
tl::expected<DefaultRepo, SeafileException>
defaultRepo(
const std::string& token,
TokenType type
) const override
{
return underlayer_api->defaultRepo(token, type);
defaultRepo() const override {
return underlayer_api->defaultRepo();
}
tl::expected<RepoInfo, SeafileException>
repoInfo(
const std::string& repo_id,
const std::string& token,
TokenType type
) const override
{
return underlayer_api->repoInfo(repo_id, token, type);
repoInfo(const std::string &repo_id) const override {
return underlayer_api->repoInfo(repo_id);
}
tl::expected<std::vector<RepoEntry>, SeafileException>
repoDir(
const std::string& repo_id,
const std::string& path,
const std::string& token,
TokenType type
) const override
{
repoDir(const std::string &repo_id, const std::string &path) const override {
const auto key = makeKey("repoDir", {repo_id, path});
if (const auto value = repo_entries_cache.get(key))
{
if (const auto value = repo_entries_cache.get(key)) {
return *value;
}
auto result = underlayer_api->repoDir(repo_id, path, token, type);
if (result)
{
auto result = underlayer_api->repoDir(repo_id, path);
if (result) {
repo_entries_cache.put(key, result.value(), default_ttl);
}
return result;
@@ -103,43 +79,22 @@ namespace seafile::api
tl::expected<AccountInfo, SeafileException>
accountInfo(
const std::string& token,
TokenType type
) const override
{
if (const auto info = account_info_cache.get(token); info.has_value())
{
return *info;
}
const auto result = underlayer_api->accountInfo(token, type);
if (result)
{
account_info_cache.put(token, result.value(), default_ttl);
}
return result;
accountInfo() const override {
return underlayer_api->accountInfo();
}
tl::expected<FileInfo, SeafileException>
fileDetail(
const std::string& repo_id,
const std::string& path,
const std::string& token,
TokenType type
) const override
{
fileDetail(const std::string &repo_id, const std::string &path) const override {
const auto key = makeKey("file", {repo_id, path});
if (const auto value = file_info_cache.get(key))
{
if (const auto value = file_info_cache.get(key)) {
return *value;
}
auto result = underlayer_api->fileDetail(repo_id, path, token, type);
auto result = underlayer_api->fileDetail(repo_id, path);
if (result)
{
if (result) {
file_info_cache.put(key, result.value(), default_ttl);
}
@@ -149,55 +104,39 @@ namespace seafile::api
tl::expected<std::string, SeafileException>
downloadFileUrl(
const std::string& repo_id,
const std::string& path,
const std::string& token,
TokenType type
) const override
{
return underlayer_api->downloadFileUrl(repo_id, path, token, type);
downloadFileUrl(const std::string &repo_id, const std::string &path) const override {
return underlayer_api->downloadFileUrl(repo_id, path);
}
tl::expected<std::string, SeafileException>
downloadFile(
const std::string& repo_id,
const std::string& path,
std::optional<size_t> start,
std::optional<size_t> end,
const std::string& token,
TokenType type
) const override
{
return underlayer_api->downloadFile(repo_id, path, start, end, token, type);
downloadFile(const std::string &repo_id, const std::string &path, std::optional<size_t> start,
std::optional<size_t> end) const override {
return underlayer_api->downloadFile(repo_id, path, start, end);
}
tl::expected<DirInfo, SeafileException>
dirDetail(
const std::string& repo_id,
const std::string& path,
const std::string& token,
TokenType type
) const override
{
dirDetail(const std::string &repo_id, const std::string &path) const override {
const auto key = makeKey("dir", {repo_id, path});
if (auto value = dir_info_cache.get(key))
{
if (auto value = dir_info_cache.get(key)) {
return *value;
}
auto result = underlayer_api->dirDetail(repo_id, path, token, type);
auto result = underlayer_api->dirDetail(repo_id, path);
if (result)
{
if (result) {
dir_info_cache.put(key, result.value(), default_ttl);
}
return result;
}
tl::expected<std::vector<RepoInfo>, SeafileException> repos(const std::string &type,
const std::string &name_contains) const override {
return underlayer_api->repos(type, name_contains);
}
};
}
#endif //SEADISK_CACHED_SEAFILE_API_HPP
+47 -25
View File
@@ -23,11 +23,14 @@
#include "seafile_api_interface.hpp"
#include "server_info.hpp"
#include "token_type.hpp"
#include "seafile/util/version.hpp"
namespace seafile::api {
class SeaFileApi final:public ISeaFileApi {
namespace seafile::api {
class SeaFileApi final : public ISeaFileApi {
//base url of the seafile api server
std::string base_url;
std::string token;
TokenType token_type = TokenType::BEARER;
/**
* @brief make a url string from given path
@@ -105,16 +108,27 @@ namespace seafile::api {
* @return token when success else SeafileException
*/
tl::expected<AuthToken, SeafileException>
authToken(const std::string &username, const std::string &password) override {
auth(const std::string &username, const std::string &password) override {
const nlohmann::json body = {
{"username", username},
{"password", password}
};
return this->post<AuthToken>("/api2/auth-token/", body);
const auto &auth_token = this->post<AuthToken>("/api2/auth-token/", body);
if (auth_token) {
this->token = auth_token->token;
if (const auto &server_info = this->serverInfo()) {
if (const auto version = util::Version(server_info->version); version.major() < 11) {
this->token_type = TokenType::TOKEN;
}
} else {
return tl::make_unexpected(server_info.error());
}
}
return auth_token;
}
tl::expected<ServerInfo, SeafileException>
serverInfo() const override{
serverInfo() const override {
const auto response = cpr::Get(
cpr::Url{makeUrl("/api2/server-info/")},
cpr::Header{
@@ -126,12 +140,10 @@ namespace seafile::api {
/**
* @brief get the default repo of user
* @param token token
* @param token_type token type
* @return default repo info
*/
tl::expected<DefaultRepo, SeafileException>
defaultRepo(const std::string &token, const TokenType token_type) const override{
defaultRepo() const override {
const auto auth = makeAuthToken(token, token_type);
const auto url = makeUrl("/api2/default-repo/");
const auto response = cpr::Get(cpr::Url{url},
@@ -143,7 +155,7 @@ namespace seafile::api {
}
tl::expected<RepoInfo, SeafileException>
repoInfo(const std::string &repo_id, const std::string &token, const TokenType token_type) const override{
repoInfo(const std::string &repo_id) const override {
const auto url = makeUrl(std::format("/api2/repos/{}/", repo_id));
const auto auth = makeAuthToken(token, token_type);
@@ -155,17 +167,32 @@ namespace seafile::api {
return parseResponse<RepoInfo>(response);
}
tl::expected<std::vector<RepoInfo>, SeafileException>
repos(const std::string &type, const std::string &name_contains) const override {
const auto url = makeUrl("/api2/repos/");
const auto auth = makeAuthToken(token, token_type);
const auto response = cpr::Get(cpr::Url{url},
cpr::Header{
{"accept", "application/json"},
{"authorization", auth}
},
cpr::Parameters{
{"type", type},
{"nameContains", name_contains}
});
return parseResponse<std::vector<RepoInfo> >(response);
}
/**
* @brief Lists all the items information in the directory
* @param repo_id repo id
* @param path path to query
* @param token token
* @param token_type token type
* @return repo entries
*/
tl::expected<std::vector<RepoEntry>, SeafileException>
repoDir(const std::string &repo_id, const std::string &path, const std::string &token,
const TokenType token_type) const override{
repoDir(const std::string &repo_id, const std::string &path) const override {
const auto url = cpr::Url{makeUrl(std::format("/api2/repos/{}/dir/", repo_id))};
const auto auth = makeAuthToken(token, token_type);
@@ -181,8 +208,7 @@ namespace seafile::api {
}
tl::expected<AccountInfo, SeafileException>
accountInfo(const std::string &token,
const TokenType token_type) const override{
accountInfo() const override {
const auto url = cpr::Url{makeUrl("/api2/account/info/")};
const auto auth = makeAuthToken(token, token_type);
@@ -195,8 +221,7 @@ namespace seafile::api {
}
tl::expected<FileInfo, SeafileException>
fileDetail(const std::string &repo_id, const std::string &path, const std::string &token,
const TokenType token_type) const override{
fileDetail(const std::string &repo_id, const std::string &path) const override {
const auto url = cpr::Url{makeUrl(std::format("/api2/repos/{}/file/detail/", repo_id))};
const auto auth = makeAuthToken(token, token_type);
@@ -211,8 +236,7 @@ namespace seafile::api {
}
tl::expected<std::string, SeafileException>
downloadFileUrl(const std::string &repo_id, const std::string &path, const std::string &token,
const TokenType token_type) const override{
downloadFileUrl(const std::string &repo_id, const std::string &path) const override {
const auto auth = makeAuthToken(token, token_type);
const auto url = cpr::Url{makeUrl(std::format("/api2/repos/{}/file/", repo_id))};
const auto response = cpr::Get(url,
@@ -230,10 +254,8 @@ namespace seafile::api {
downloadFile(const std::string &repo_id,
const std::string &path,
const std::optional<size_t> start,
const std::optional<size_t> end,
const std::string &token,
const TokenType token_type) const override{
if (auto download_url = downloadFileUrl(repo_id, path, token, token_type); download_url.has_value()) {
const std::optional<size_t> end) const override {
if (auto download_url = downloadFileUrl(repo_id, path); download_url.has_value()) {
const auto auth = makeAuthToken(token, token_type);
const auto url = cpr::Url{download_url.value()};
auto header = cpr::Header{
@@ -255,8 +277,8 @@ namespace seafile::api {
}
}
tl::expected<DirInfo, SeafileException> dirDetail(const std::string &repo_id, const std::string &path,
const std::string &token, const TokenType token_type) const override{
tl::expected<DirInfo, SeafileException>
dirDetail(const std::string &repo_id, const std::string &path) const override {
const auto auth = makeAuthToken(token, token_type);
const auto url = cpr::Url{makeUrl(std::format("/api/v2.1/repos/{}/dir/detail/", repo_id))};
const auto response = cpr::Get(url, cpr::Header{
+50 -68
View File
@@ -23,94 +23,76 @@
namespace seafile::api {
class ISeaFileApi {
public:
virtual ~ISeaFileApi() = default;
class ISeaFileApi {
public:
virtual ~ISeaFileApi() = default;
virtual tl::expected<AuthToken, SeafileException>
authToken(
const std::string& username,
const std::string& password
) = 0;
virtual tl::expected<AuthToken, SeafileException>
auth(
const std::string &username,
const std::string &password
) = 0;
virtual tl::expected<ServerInfo, SeafileException>
serverInfo() const = 0;
virtual tl::expected<ServerInfo, SeafileException>
serverInfo() const = 0;
virtual tl::expected<DefaultRepo, SeafileException>
defaultRepo(
const std::string& token,
TokenType token_type
) const = 0;
virtual tl::expected<DefaultRepo, SeafileException>
defaultRepo() const = 0;
virtual tl::expected<RepoInfo, SeafileException>
repoInfo(
const std::string& repo_id,
const std::string& token,
TokenType token_type
) const = 0;
virtual tl::expected<RepoInfo, SeafileException>
repoInfo(
const std::string &repo_id
) const = 0;
virtual tl::expected<std::vector<RepoEntry>, SeafileException>
repoDir(
const std::string& repo_id,
const std::string& path,
const std::string& token,
TokenType token_type
) const = 0;
virtual tl::expected<std::vector<RepoEntry>, SeafileException>
repoDir(
const std::string &repo_id,
const std::string &path
) const = 0;
virtual tl::expected<std::vector<RepoInfo>, SeafileException>
repos(const std::string &type, const std::string &name_contains) const = 0;
virtual tl::expected<AccountInfo, SeafileException>
accountInfo(
const std::string& token,
TokenType token_type
) const = 0;
virtual tl::expected<AccountInfo, SeafileException>
accountInfo() const = 0;
virtual tl::expected<FileInfo, SeafileException>
fileDetail(
const std::string& repo_id,
const std::string& path,
const std::string& token,
TokenType token_type
) const = 0;
virtual tl::expected<FileInfo, SeafileException>
fileDetail(
const std::string &repo_id,
const std::string &path
) const = 0;
virtual tl::expected<std::string, SeafileException>
downloadFileUrl(
const std::string& repo_id,
const std::string& path,
const std::string& token,
TokenType token_type
) const = 0;
virtual tl::expected<std::string, SeafileException>
downloadFileUrl(
const std::string &repo_id,
const std::string &path
) const = 0;
virtual tl::expected<std::string, SeafileException>
downloadFile(
const std::string& repo_id,
const std::string& path,
std::optional<size_t> start,
std::optional<size_t> end,
const std::string& token,
TokenType token_type
) const = 0;
virtual tl::expected<std::string, SeafileException>
downloadFile(
const std::string &repo_id,
const std::string &path,
std::optional<size_t> start,
std::optional<size_t> end
) const = 0;
virtual tl::expected<DirInfo, SeafileException>
dirDetail(
const std::string& repo_id,
const std::string& path,
const std::string& token,
TokenType token_type
) const = 0;
};
virtual tl::expected<DirInfo, SeafileException>
dirDetail(
const std::string &repo_id,
const std::string &path
) const = 0;
};
}
#endif //SEADISK_SEAFILE_API_INTERFACE_HPP
@@ -23,8 +23,6 @@ namespace seafile::fs
std::string repo_id;
std::string token;
TokenType token_type = TokenType::TOKEN;
std::shared_ptr<ISeaFileApi> api;
std::wstring volume_label;
+15 -5
View File
@@ -29,7 +29,7 @@ namespace seafile::fs
[[nodiscard]] tl::expected<std::string, api::SeafileException> defaultRepoId() const;
///初始化数据库信息
[[nodiscard]] tl::expected<void, api::SeafileException> init() const;
[[nodiscard]] tl::expected<void, api::SeafileException> init();
/// 检查是否已经更新到最新
/// @return true 已经最新,false 需要更新
@@ -39,7 +39,19 @@ namespace seafile::fs
tl::expected<void, api::SeafileException> checkAndSync(const std::string& repo_id);
/// 同步元数据
[[nodiscard]] tl::expected<void, api::SeafileException> sync(const std::string& repo_id) const;
[[nodiscard]] tl::expected<void, api::SeafileException> syncRepoEntry(const std::string& repo_id) const;
/// 同步用户信息
tl::expected<void, api::SeafileException> syncUserInfo();
/// 同步repo信息
tl::expected<void, api::SeafileException> syncRepos();
/// 同步
tl::expected<void, api::SeafileException> sync();
std::filesystem::path storePath() const;
/// 获取路径信息
/// @param path 路径
@@ -51,10 +63,8 @@ namespace seafile::fs
struct Database;
std::unique_ptr<Database> database;
std::string api_server;
std::string user;
std::string username;
std::string password;
std::string token;
api::TokenType token_type = api::TokenType::TOKEN;
api::SeaFileApi api;
};
}
+55
View File
@@ -0,0 +1,55 @@
//
// Created by Shell on 2026/7/21.
//
#ifndef SEADISK_VERSION_HPP
#define SEADISK_VERSION_HPP
#include <string>
#include <optional>
namespace seafile::util
{
/**
* @brief Semantic version parser.
*
* Supports:
* 10
* 10.0
* 10.0.2
*/
class Version final
{
public:
Version() = default;
explicit Version(const std::string& version);
[[nodiscard]]
int major() const noexcept;
[[nodiscard]]
std::optional<int> minor() const noexcept;
[[nodiscard]]
std::optional<int> patch() const noexcept;
[[nodiscard]]
std::string toString() const;
bool operator==(const Version& other) const;
bool operator<(const Version& other) const;
private:
void parse(const std::string& version);
private:
int major_{0};
std::optional<int> minor_;
std::optional<int> patch_;
};
}
#endif //SEADISK_VERSION_HPP