diff --git a/repertory/librepertory/include/providers/s3/s3_provider.hpp b/repertory/librepertory/include/providers/s3/s3_provider.hpp index 1ee77b0e..d9091657 100644 --- a/repertory/librepertory/include/providers/s3/s3_provider.hpp +++ b/repertory/librepertory/include/providers/s3/s3_provider.hpp @@ -62,6 +62,10 @@ private: [[nodiscard]] auto decrypt_object_name(std::string &object_name) const -> api_error; + [[nodiscard]] auto + get_last_modified(bool directory, + const std::string &api_path) const -> std::uint64_t; + [[nodiscard]] auto get_object_info(bool directory, const std::string &api_path, bool &is_encrypted, std::string &object_name, diff --git a/repertory/librepertory/include/types/s3.hpp b/repertory/librepertory/include/types/s3.hpp index 6ac87c98..a3822496 100644 --- a/repertory/librepertory/include/types/s3.hpp +++ b/repertory/librepertory/include/types/s3.hpp @@ -28,20 +28,6 @@ #include "utils/utils.hpp" namespace repertory { -namespace utils::aws { -#if defined(_WIN32) -[[nodiscard]] inline auto format_time(std::uint64_t t) -> std::uint64_t { - auto ft = utils::time::unix_time_to_filetime(t); - return static_cast(ft.dwHighDateTime) << 32u | - ft.dwLowDateTime; -} -#else // _WIN32 -[[nodiscard]] inline auto format_time(std::uint64_t t) -> std::uint64_t { - return t; -} -#endif // _WIN32 -} // namespace utils::aws - using get_key_callback = std::function; using get_api_file_token_callback = diff --git a/repertory/librepertory/src/providers/s3/s3_provider.cpp b/repertory/librepertory/src/providers/s3/s3_provider.cpp index 18c4b4c8..4ff75e11 100644 --- a/repertory/librepertory/src/providers/s3/s3_provider.cpp +++ b/repertory/librepertory/src/providers/s3/s3_provider.cpp @@ -37,6 +37,7 @@ #include "utils/string.hpp" #include "utils/time.hpp" +namespace {} namespace repertory { s3_provider::s3_provider(app_config &config, i_http_comm &comm) : base_provider(config, comm) { @@ -195,6 +196,8 @@ auto s3_provider::create_path_directories( auto res = get_item_meta(cur_path, meta); if (res == api_error::item_not_found) { auto dir = create_api_file(cur_path, cur_key, 0U); + dir.accessed_date = dir.changed_date = dir.creation_date = + dir.modified_date = get_last_modified(true, cur_path); get_api_item_added()(true, dir); continue; } @@ -325,7 +328,7 @@ auto s3_provider::get_directory_items_impl( } const auto add_directory_item = - [&](bool directory, const std::string &name, + [&](bool directory, const std::string &name, std::uint64_t last_modified, std::function get_size) -> api_error { auto child_api_path = @@ -354,6 +357,8 @@ auto s3_provider::get_directory_items_impl( } else { auto file = create_api_file(child_api_path, child_object_name, dir_item.size); + file.accessed_date = file.changed_date = file.creation_date = + file.modified_date = last_modified; ret = add_if_not_found(file, child_object_name); if (ret != api_error::success) { return ret; @@ -374,7 +379,7 @@ auto s3_provider::get_directory_items_impl( auto node_list = doc.select_nodes("/ListBucketResult/CommonPrefixes/Prefix"); for (auto &&node : node_list) { add_directory_item( - true, node.node().text().as_string(), + true, node.node().text().as_string(), utils::time::get_time_now(), [](const directory_item &) -> std::uint64_t { return 0U; }); } @@ -384,8 +389,10 @@ auto s3_provider::get_directory_items_impl( node.node().select_node("Key").node().text().as_string()); if (child_object_name != utils::path::create_api_path(prefix)) { auto size = node.node().select_node("Size").node().text().as_ullong(); + auto last_modified = convert_api_date( + node.node().select_node("LastModified").node().text().as_string()); add_directory_item( - false, child_object_name, + false, child_object_name, last_modified, [&is_encrypted, &size](const directory_item &) -> std::uint64_t { return is_encrypted ? utils::encryption::encrypting_reader:: calculate_decrypted_size(size) @@ -413,17 +420,16 @@ auto s3_provider::get_file(const std::string &api_path, return res; } - file.accessed_date = utils::time::get_time_now(); file.api_path = api_path; - file.api_parent = utils::path::get_parent_api_path(file.api_path); - file.changed_date = utils::aws::format_time(result.last_modified); - file.creation_date = utils::aws::format_time(result.last_modified); + file.api_parent = utils::path::get_parent_api_path(api_path); + file.accessed_date = file.changed_date = file.creation_date = + file.modified_date = result.last_modified; file.file_size = is_encrypted ? utils::encryption::encrypting_reader::calculate_decrypted_size( result.content_length) : result.content_length; - file.modified_date = utils::aws::format_time(result.last_modified); + file.key = is_encrypted ? utils::path::create_api_path(api_path) : ""; return add_if_not_found(file, object_name); } catch (const std::exception &e) { utils::error::raise_error(function_name, e, "exception occurred"); @@ -468,18 +474,18 @@ auto s3_provider::get_file_list(api_file_list &list) const -> api_error { api_file file{}; file.api_path = utils::path::create_api_path(api_path); file.api_parent = utils::path::get_parent_api_path(file.api_path); - file.accessed_date = utils::time::get_time_now(); - file.changed_date = convert_api_date( - node.node().select_node("LastModified").node().text().as_string()); - file.creation_date = file.changed_date; + file.accessed_date = file.changed_date = file.creation_date = + file.modified_date = convert_api_date(node.node() + .select_node("LastModified") + .node() + .text() + .as_string()); file.file_size = is_encrypted ? utils::encryption::encrypting_reader::calculate_decrypted_size( size) : size; file.key = is_encrypted ? utils::path::create_api_path(api_path) : ""; - file.modified_date = file.changed_date; - auto err = add_if_not_found(file, api_path); if (err != api_error::success) { return err; @@ -492,6 +498,17 @@ auto s3_provider::get_file_list(api_file_list &list) const -> api_error { return api_error::success; } +auto s3_provider::get_last_modified( + bool directory, const std::string &api_path) const -> std::uint64_t { + bool is_encrypted{}; + std::string object_name; + head_object_result result{}; + return (get_object_info(directory, api_path, is_encrypted, object_name, + result) == api_error::success) + ? result.last_modified + : utils::time::get_time_now(); +} + auto s3_provider::get_object_info( bool directory, const std::string &api_path, bool &is_encrypted, std::string &object_name, head_object_result &result) const -> api_error {