|  |  | 
 |  |  | #include "bom.hpp" | 
 |  |  |  | 
 |  |  | #include "book.hpp" | 
 |  |  | #include "ftplibpp/ftplib.h" | 
 |  |  | #include "rapidxml/rapidxml.hpp" | 
 |  |  | #include <cstddef> | 
 |  |  | #include <cstdio> | 
 |  |  | #include <curl/curl.h> | 
 |  |  | #include <stdio.h> | 
 |  |  | #include <fstream> | 
 |  |  | #include <iterator> | 
 |  |  | #include <string> | 
 |  |  | #include <unordered_map> | 
 |  |  | #include <vector> | 
 |  |  |  | 
 |  |  | namespace bom | 
 |  |  | { | 
 |  |  | ftplib* ftp; | 
 |  |  |  | 
 |  |  | static size_t my_fwrite(void* buffer, size_t size, size_t nmemb, void* stream) | 
 |  |  | void initialise() | 
 |  |  | { | 
 |  |  |    FILE* out = (FILE*)stream; | 
 |  |  |    if (!out) { | 
 |  |  |       out = tmpfile(); | 
 |  |  |       if (!out) { | 
 |  |  |          return -1; | 
 |  |  |       } | 
 |  |  |    } | 
 |  |  |    return fwrite(buffer, size, nmemb, out); | 
 |  |  |    ftp = new ftplib(); | 
 |  |  |    ftp->Connect("ftp.bom.gov.au:21"); | 
 |  |  |    ftp->Login("anonymous", ""); | 
 |  |  | } | 
 |  |  |  | 
 |  |  | void destroy() | 
 |  |  | { | 
 |  |  |    ftp->Quit(); | 
 |  |  |    delete ftp; | 
 |  |  | } | 
 |  |  |  | 
 |  |  | void updateBom(std::unordered_map<std::string, book::Book>& bs) | 
 |  |  | { | 
 |  |  |    CURL* curl; | 
 |  |  |    CURLcode res; | 
 |  |  |    FILE* f{NULL}; | 
 |  |  |    curl_global_init(CURL_GLOBAL_DEFAULT); | 
 |  |  |    curl = curl_easy_init(); | 
 |  |  |    if (curl) { | 
 |  |  |       curl_easy_setopt(curl, CURLOPT_URL, | 
 |  |  |                        "ftp://ftp.bom.gov.au/anon/gen/fwo/IDN60920.xml"); | 
 |  |  |       curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite); | 
 |  |  |       curl_easy_setopt(curl, CURLOPT_WRITEDATA, &f); | 
 |  |  |       curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); | 
 |  |  |       res = curl_easy_perform(curl); | 
 |  |  |       curl_easy_cleanup(curl); | 
 |  |  |       if (CURLE_OK != res) { | 
 |  |  |          fprintf(stderr, "Curl failed: %d\n", res); | 
 |  |  |    ftp->Get("bom_data.xml", "/anon/gen/fwo/IDN60920.xml", | 
 |  |  |             ftplib::transfermode::ascii); | 
 |  |  |    std::ifstream fs("bom_data.xml"); | 
 |  |  |    std::vector<char> buffer{std::istreambuf_iterator<char>(fs), | 
 |  |  |                             istreambuf_iterator<char>()}; | 
 |  |  |    buffer.push_back('\0'); | 
 |  |  |    rapidxml::xml_document<> d; | 
 |  |  |    d.parse<0>(&buffer[0]); | 
 |  |  |    // Walk stations | 
 |  |  |    for (rapidxml::xml_node<>* n = d.first_node()->last_node()->first_node(); n; | 
 |  |  |         n = n->next_sibling()) { | 
 |  |  |       int bom_id = std::stoi(n->first_attribute()->next_attribute()->value()); | 
 |  |  |       for (auto& i : bs) { | 
 |  |  |          if (i.second.stationId == bom_id) { | 
 |  |  |             // Should be apparent temp | 
 |  |  |             i.second.bomPrice = std::stod(n->first_node() | 
 |  |  |                                               ->first_node() | 
 |  |  |                                               ->first_node() | 
 |  |  |                                               ->first_node() | 
 |  |  |                                               ->value()); | 
 |  |  |          } | 
 |  |  |       } | 
 |  |  |    } | 
 |  |  |    if (f) { | 
 |  |  |       fclose(f); | 
 |  |  |    } | 
 |  |  |    curl_global_cleanup(); | 
 |  |  | } | 
 |  |  | } // namespace bom |