static inline std::map<const ProgressBar *, int> lines;
static inline int max_line = 0;
+ std::string filename;
+ size_t len = 0;
+
static void cleanup(const ProgressBar * line) {
lines.erase(line);
if (lines.empty()) {
}
public:
- ProgressBar() = default;
+ ProgressBar(const std::string & url = "") : filename(url) {
+ if (auto pos = filename.rfind('/'); pos != std::string::npos) {
+ filename = filename.substr(pos + 1);
+ }
+ if (auto pos = filename.find('?'); pos != std::string::npos) {
+ filename = filename.substr(0, pos);
+ }
+ for (size_t i = 0; i < filename.size(); ++i) {
+ if ((filename[i] & 0xC0) != 0x80) {
+ if (len++ == 39) {
+ filename.resize(i);
+ filename += "…";
+ break;
+ }
+ }
+ }
+ }
~ProgressBar() {
std::lock_guard<std::mutex> lock(mutex);
}
void update(size_t current, size_t total) {
- if (!is_output_a_tty()) {
- return;
- }
-
- if (!total) {
+ if (!total || !is_output_a_tty()) {
return;
}
}
int lines_up = max_line - lines[this];
- size_t width = 50;
+ size_t bar = 55 - len;
size_t pct = (100 * current) / total;
- size_t pos = (width * current) / total;
-
- std::cout << "\033[s";
+ size_t pos = (bar * current) / total;
if (lines_up > 0) {
std::cout << "\033[" << lines_up << "A";
}
- std::cout << "\033[2K\r["
- << std::string(pos, '=')
- << (pos < width ? ">" : "")
- << std::string(width - pos, ' ')
- << "] " << std::setw(3) << pct << "% ("
- << current / (1024 * 1024) << " MB / "
- << total / (1024 * 1024) << " MB) "
- << "\033[u";
+ std::cout << '\r' << "Downloading " << filename << " ";
+
+ for (size_t i = 0; i < bar; ++i) {
+ std::cout << (i < pos ? "—" : " ");
+ }
+ std::cout << std::setw(4) << pct << "%\033[K";
- std::cout.flush();
+ if (lines_up > 0) {
+ std::cout << "\033[" << lines_up << "B";
+ }
+ std::cout << '\r' << std::flush;
if (current == total) {
- cleanup(this);
+ cleanup(this);
}
}
const char * func = __func__; // avoid __func__ inside a lambda
size_t downloaded = existing_size;
size_t progress_step = 0;
- ProgressBar bar;
+ ProgressBar bar(resolve_path);
auto res = cli.Get(resolve_path, headers,
[&](const httplib::Response &response) {
const bool file_exists = std::filesystem::exists(path);
if (file_exists && skip_etag) {
- LOG_INF("%s: using cached file: %s\n", __func__, path.c_str());
+ LOG_DBG("%s: using cached file: %s\n", __func__, path.c_str());
return 304; // 304 Not Modified - fake cached response
}
if (file_exists) {
last_etag = read_etag(path);
} else {
- LOG_INF("%s: no previous model file found %s\n", __func__, path.c_str());
+ LOG_DBG("%s: no previous model file found %s\n", __func__, path.c_str());
}
auto head = cli.Head(parts.path);
if (file_exists) {
if (etag.empty()) {
- LOG_INF("%s: using cached file (no server etag): %s\n", __func__, path.c_str());
+ LOG_DBG("%s: using cached file (no server etag): %s\n", __func__, path.c_str());
return 304; // 304 Not Modified - fake cached response
}
if (!last_etag.empty() && last_etag == etag) {
- LOG_INF("%s: using cached file (same etag): %s\n", __func__, path.c_str());
+ LOG_DBG("%s: using cached file (same etag): %s\n", __func__, path.c_str());
return 304; // 304 Not Modified - fake cached response
}
if (remove(path.c_str()) != 0) {
}
}
- LOG_INF("%s: downloading from %s to %s (etag:%s)...\n",
+ LOG_DBG("%s: downloading from %s to %s (etag:%s)...\n",
__func__, common_http_show_masked_url(parts).c_str(),
path_temporary.c_str(), etag.c_str());
return -1;
}
- LOG_INF("%s: using cached file (offline mode): %s\n", __func__, path.c_str());
+ LOG_DBG("%s: using cached file (offline mode): %s\n", __func__, path.c_str());
return 304; // Not Modified - fake cached response
}