mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 17:20:06 +00:00 
			
		
		
		
	Provide interface to request multiple text product lists in parallel
This commit is contained in:
		
							parent
							
								
									33c73ef0e2
								
							
						
					
					
						commit
						7a8a0302e0
					
				
					 2 changed files with 118 additions and 68 deletions
				
			
		|  | @ -4,6 +4,7 @@ | ||||||
| 
 | 
 | ||||||
| #include <memory> | #include <memory> | ||||||
| #include <string> | #include <string> | ||||||
|  | #include <vector> | ||||||
| 
 | 
 | ||||||
| #include <boost/outcome/result.hpp> | #include <boost/outcome/result.hpp> | ||||||
| 
 | 
 | ||||||
|  | @ -29,6 +30,10 @@ public: | ||||||
|    ListTextProducts(std::chrono::sys_time<std::chrono::days> date, |    ListTextProducts(std::chrono::sys_time<std::chrono::days> date, | ||||||
|                     std::optional<std::string_view>          cccc = {}, |                     std::optional<std::string_view>          cccc = {}, | ||||||
|                     std::optional<std::string_view>          pil  = {}); |                     std::optional<std::string_view>          pil  = {}); | ||||||
|  |    static boost::outcome_v2::result<std::vector<std::string>> | ||||||
|  |    ListTextProducts(std::vector<std::chrono::sys_time<std::chrono::days>> dates, | ||||||
|  |                     std::vector<std::string_view> ccccs = {}, | ||||||
|  |                     std::vector<std::string_view> pils  = {}); | ||||||
| 
 | 
 | ||||||
|    static std::vector<std::shared_ptr<awips::TextProductFile>> |    static std::vector<std::shared_ptr<awips::TextProductFile>> | ||||||
|    LoadTextProducts(const std::vector<std::string>& textProducts); |    LoadTextProducts(const std::vector<std::string>& textProducts); | ||||||
|  |  | ||||||
|  | @ -6,6 +6,7 @@ | ||||||
| 
 | 
 | ||||||
| #include <boost/json.hpp> | #include <boost/json.hpp> | ||||||
| #include <cpr/cpr.h> | #include <cpr/cpr.h> | ||||||
|  | #include <range/v3/view/cartesian_product.hpp> | ||||||
| 
 | 
 | ||||||
| #if (__cpp_lib_chrono < 201907L) | #if (__cpp_lib_chrono < 201907L) | ||||||
| #   include <date/date.h> | #   include <date/date.h> | ||||||
|  | @ -41,8 +42,25 @@ IemApiProvider& IemApiProvider::operator=(IemApiProvider&&) noexcept = default; | ||||||
| 
 | 
 | ||||||
| boost::outcome_v2::result<std::vector<std::string>> | boost::outcome_v2::result<std::vector<std::string>> | ||||||
| IemApiProvider::ListTextProducts(std::chrono::sys_time<std::chrono::days> date, | IemApiProvider::ListTextProducts(std::chrono::sys_time<std::chrono::days> date, | ||||||
|                                  std::optional<std::string_view>          cccc, |                                  std::optional<std::string_view> optionalCccc, | ||||||
|                                  std::optional<std::string_view>          pil) |                                  std::optional<std::string_view> optionalPil) | ||||||
|  | { | ||||||
|  |    std::string_view cccc = | ||||||
|  |       optionalCccc.has_value() ? optionalCccc.value() : std::string_view {}; | ||||||
|  |    std::string_view pil = | ||||||
|  |       optionalPil.has_value() ? optionalPil.value() : std::string_view {}; | ||||||
|  | 
 | ||||||
|  |    return ListTextProducts( | ||||||
|  |       std::vector<std::chrono::sys_time<std::chrono::days>> {date}, | ||||||
|  |       {cccc}, | ||||||
|  |       {pil}); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | boost::outcome_v2::result<std::vector<std::string>> | ||||||
|  | IemApiProvider::ListTextProducts( | ||||||
|  |    std::vector<std::chrono::sys_time<std::chrono::days>> dates, | ||||||
|  |    std::vector<std::string_view>                         ccccs, | ||||||
|  |    std::vector<std::string_view>                         pils) | ||||||
| { | { | ||||||
|    using namespace std::chrono; |    using namespace std::chrono; | ||||||
| 
 | 
 | ||||||
|  | @ -57,28 +75,50 @@ IemApiProvider::ListTextProducts(std::chrono::sys_time<std::chrono::days> date, | ||||||
| #   define kDateFormat "%Y-%m-%d" | #   define kDateFormat "%Y-%m-%d" | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|    auto parameters = cpr::Parameters {{"date", df::format(kDateFormat, date)}}; |    if (ccccs.empty()) | ||||||
|  |    { | ||||||
|  |       ccccs.push_back({}); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (pils.empty()) | ||||||
|  |    { | ||||||
|  |       pils.push_back({}); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    std::vector<cpr::AsyncResponse> responses {}; | ||||||
|  | 
 | ||||||
|  |    for (const auto& [date, cccc, pil] : | ||||||
|  |         ranges::views::cartesian_product(dates, ccccs, pils)) | ||||||
|  |    { | ||||||
|  |       auto parameters = | ||||||
|  |          cpr::Parameters {{"date", df::format(kDateFormat, date)}}; | ||||||
| 
 | 
 | ||||||
|       // WMO Source Code
 |       // WMO Source Code
 | ||||||
|    if (cccc.has_value()) |       if (!cccc.empty()) | ||||||
|       { |       { | ||||||
|       parameters.Add({"cccc", std::string {cccc.value()}}); |          parameters.Add({"cccc", std::string {cccc}}); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       // AFOS / AWIPS ID / 3-6 length identifier
 |       // AFOS / AWIPS ID / 3-6 length identifier
 | ||||||
|    if (pil.has_value()) |       if (!pil.empty()) | ||||||
|       { |       { | ||||||
|       parameters.Add({"pil", std::string {pil.value()}}); |          parameters.Add({"pil", std::string {pil}}); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|    auto response = |       responses.emplace_back( | ||||||
|       cpr::Get(cpr::Url {kBaseUrl_ + kListNwsTextProductsEndpoint_}, |          cpr::GetAsync(cpr::Url {kBaseUrl_ + kListNwsTextProductsEndpoint_}, | ||||||
|                        network::cpr::GetHeader(), |                        network::cpr::GetHeader(), | ||||||
|                parameters); |                        parameters)); | ||||||
|    boost::json::value json = util::json::ReadJsonString(response.text); |    } | ||||||
| 
 | 
 | ||||||
|    std::vector<std::string> textProducts {}; |    std::vector<std::string> textProducts {}; | ||||||
| 
 | 
 | ||||||
|  |    for (auto& asyncResponse : responses) | ||||||
|  |    { | ||||||
|  |       auto response = asyncResponse.get(); | ||||||
|  | 
 | ||||||
|  |       boost::json::value json = util::json::ReadJsonString(response.text); | ||||||
|  | 
 | ||||||
|       if (response.status_code == cpr::status::HTTP_OK) |       if (response.status_code == cpr::status::HTTP_OK) | ||||||
|       { |       { | ||||||
|          try |          try | ||||||
|  | @ -107,8 +147,10 @@ IemApiProvider::ListTextProducts(std::chrono::sys_time<std::chrono::days> date, | ||||||
|          try |          try | ||||||
|          { |          { | ||||||
|             // Log bad request details
 |             // Log bad request details
 | ||||||
|          auto badRequest = boost::json::value_to<types::iem::BadRequest>(json); |             auto badRequest = | ||||||
|          logger_->warn("ListTextProducts bad request: {}", badRequest.detail_); |                boost::json::value_to<types::iem::BadRequest>(json); | ||||||
|  |             logger_->warn("ListTextProducts bad request: {}", | ||||||
|  |                           badRequest.detail_); | ||||||
|          } |          } | ||||||
|          catch (const std::exception& ex) |          catch (const std::exception& ex) | ||||||
|          { |          { | ||||||
|  | @ -125,7 +167,8 @@ IemApiProvider::ListTextProducts(std::chrono::sys_time<std::chrono::days> date, | ||||||
|          try |          try | ||||||
|          { |          { | ||||||
|             // Log validation error details
 |             // Log validation error details
 | ||||||
|          auto error = boost::json::value_to<types::iem::ValidationError>(json); |             auto error = | ||||||
|  |                boost::json::value_to<types::iem::ValidationError>(json); | ||||||
|             logger_->warn("ListTextProducts validation error: {}", |             logger_->warn("ListTextProducts validation error: {}", | ||||||
|                           error.detail_.at(0).msg_); |                           error.detail_.at(0).msg_); | ||||||
|          } |          } | ||||||
|  | @ -140,11 +183,13 @@ IemApiProvider::ListTextProducts(std::chrono::sys_time<std::chrono::days> date, | ||||||
|       } |       } | ||||||
|       else |       else | ||||||
|       { |       { | ||||||
|       logger_->warn("Could not list text products: {}", response.status_line); |          logger_->warn("Could not list text products: {}", | ||||||
|  |                        response.status_line); | ||||||
| 
 | 
 | ||||||
|          return boost::system::errc::make_error_code( |          return boost::system::errc::make_error_code( | ||||||
|             boost::system::errc::no_message); |             boost::system::errc::no_message); | ||||||
|       } |       } | ||||||
|  |    } | ||||||
| 
 | 
 | ||||||
|    return textProducts; |    return textProducts; | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat