mirror of
https://github.com/abraunegg/onedrive
synced 2024-06-14 11:45:06 +02:00
220a00bbdf
* Fixes in order to compile on an Android host Co-authored-by: Jean-Yves Didier <jeanyves.didier@univ-evry.fr>
157 lines
3.4 KiB
D
157 lines
3.4 KiB
D
module progress;
|
|
|
|
import std.stdio;
|
|
import std.range;
|
|
import std.format;
|
|
import std.datetime;
|
|
import core.sys.posix.unistd;
|
|
import core.sys.posix.sys.ioctl;
|
|
|
|
class Progress
|
|
{
|
|
private:
|
|
|
|
immutable static size_t default_width = 80;
|
|
size_t max_width = 40;
|
|
size_t width = default_width;
|
|
|
|
ulong start_time;
|
|
string caption = "Progress";
|
|
size_t iterations;
|
|
size_t counter;
|
|
|
|
|
|
size_t getTerminalWidth() {
|
|
size_t column = default_width;
|
|
version (CRuntime_Musl) {
|
|
} else version(Android) {
|
|
} else {
|
|
winsize ws;
|
|
if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1 && ws.ws_col > 0) {
|
|
column = ws.ws_col;
|
|
}
|
|
}
|
|
|
|
return column;
|
|
}
|
|
|
|
|
|
void clear() {
|
|
write("\r");
|
|
for(auto i = 0; i < width; i++) write(" ");
|
|
write("\r");
|
|
}
|
|
|
|
|
|
int calc_eta() {
|
|
immutable auto ratio = cast(double)counter / iterations;
|
|
auto current_time = Clock.currTime.toUnixTime();
|
|
auto duration = cast(int)(current_time - start_time);
|
|
int hours, minutes, seconds;
|
|
double elapsed = (current_time - start_time);
|
|
int eta_sec = cast(int)((elapsed / ratio) - elapsed);
|
|
|
|
// Return an ETA or Duration?
|
|
if (eta_sec != 0){
|
|
return eta_sec;
|
|
} else {
|
|
return duration;
|
|
}
|
|
}
|
|
|
|
|
|
string progressbarText(string header_text, string footer_text) {
|
|
immutable auto ratio = cast(double)counter / iterations;
|
|
string result = "";
|
|
|
|
double bar_length = width - header_text.length - footer_text.length;
|
|
if(bar_length > max_width && max_width > 0) {
|
|
bar_length = max_width;
|
|
}
|
|
size_t i = 0;
|
|
for(; i < ratio * bar_length; i++) result ~= "o";
|
|
for(; i < bar_length; i++) result ~= " ";
|
|
|
|
return header_text ~ result ~ footer_text;
|
|
}
|
|
|
|
|
|
void print() {
|
|
immutable auto ratio = cast(double)counter / iterations;
|
|
auto header = appender!string();
|
|
auto footer = appender!string();
|
|
|
|
header.formattedWrite("%s %3d%% |", caption, cast(int)(ratio * 100));
|
|
|
|
if(counter <= 0 || ratio == 0.0) {
|
|
footer.formattedWrite("| ETA --:--:--:");
|
|
} else {
|
|
int h, m, s;
|
|
dur!"seconds"(calc_eta())
|
|
.split!("hours", "minutes", "seconds")(h, m, s);
|
|
if (counter != iterations){
|
|
footer.formattedWrite("| ETA %02d:%02d:%02d ", h, m, s);
|
|
} else {
|
|
footer.formattedWrite("| DONE IN %02d:%02d:%02d ", h, m, s);
|
|
}
|
|
}
|
|
|
|
write(progressbarText(header.data, footer.data));
|
|
}
|
|
|
|
|
|
void update() {
|
|
width = getTerminalWidth();
|
|
|
|
clear();
|
|
|
|
print();
|
|
stdout.flush();
|
|
}
|
|
|
|
|
|
public:
|
|
|
|
this(size_t iterations) {
|
|
if(iterations <= 0) iterations = 1;
|
|
|
|
counter = -1;
|
|
this.iterations = iterations;
|
|
start_time = Clock.currTime.toUnixTime;
|
|
}
|
|
|
|
@property {
|
|
string title() { return caption; }
|
|
string title(string text) { return caption = text; }
|
|
}
|
|
|
|
@property {
|
|
size_t count() { return counter; }
|
|
size_t count(size_t val) {
|
|
if(val > iterations) val = iterations;
|
|
return counter = val;
|
|
}
|
|
}
|
|
|
|
@property {
|
|
size_t maxWidth() { return max_width; }
|
|
size_t maxWidth(size_t w) {
|
|
return max_width = w;
|
|
}
|
|
}
|
|
|
|
void reset() {
|
|
counter = -1;
|
|
start_time = Clock.currTime.toUnixTime;
|
|
}
|
|
|
|
void next() {
|
|
counter++;
|
|
if(counter > iterations) counter = iterations;
|
|
|
|
update();
|
|
}
|
|
|
|
|
|
}
|