// // Created by Shell on 2026-07-14. // #ifndef SEADISK_CACHED_SEAFILE_API_HPP #define SEADISK_CACHED_SEAFILE_API_HPP #include "seafile_api_interface.hpp" #include "seafile/cache/cache.hpp" namespace seafile::api { class CachedSeafileApi final : public ISeaFileApi { mutable cache::Cache file_info_cache; mutable cache::Cache dir_info_cache; mutable cache::Cache > repo_entries_cache; mutable cache::Cache account_info_cache; std::shared_ptr underlayer_api; std::chrono::seconds default_ttl = std::chrono::seconds(300); static std::string makeKey( std::string_view prefix, std::initializer_list args ) { std::string key(prefix); for (auto &arg: args) { key += ':'; key += arg; } return key; } public: explicit CachedSeafileApi(std::shared_ptr api) : underlayer_api(std::move(api)) { }; tl::expected auth( const std::string &username, const std::string &password ) override { return underlayer_api->auth(username, password); } tl::expected serverInfo() const override { return underlayer_api->serverInfo(); } tl::expected defaultRepo() const override { return underlayer_api->defaultRepo(); } tl::expected repoInfo(const std::string &repo_id) const override { return underlayer_api->repoInfo(repo_id); } tl::expected, SeafileException> 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)) { return *value; } auto result = underlayer_api->repoDir(repo_id, path); if (result) { repo_entries_cache.put(key, result.value(), default_ttl); } return result; } tl::expected accountInfo() const override { return underlayer_api->accountInfo(); } tl::expected 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)) { return *value; } auto result = underlayer_api->fileDetail(repo_id, path); if (result) { file_info_cache.put(key, result.value(), default_ttl); } return result; } tl::expected downloadFileUrl(const std::string &repo_id, const std::string &path) const override { return underlayer_api->downloadFileUrl(repo_id, path); } tl::expected downloadFile(const std::string &repo_id, const std::string &path, std::optional start, std::optional end) const override { return underlayer_api->downloadFile(repo_id, path, start, end); } tl::expected 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)) { return *value; } auto result = underlayer_api->dirDetail(repo_id, path); if (result) { dir_info_cache.put(key, result.value(), default_ttl); } return result; } tl::expected, 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