X-Git-Url: https://git.distorted.org.uk/~mdw/tripe-android/blobdiff_plain/25c3546915ef2105c0d53983939da840ddbde795..c8292b34485a2e00e676023d4164dd5841e4659f:/progress.scala diff --git a/progress.scala b/progress.scala new file mode 100644 index 0000000..ddd2b6a --- /dev/null +++ b/progress.scala @@ -0,0 +1,90 @@ +/* -*-scala-*- + * + * Reporting progress for long-running jobs + * + * (c) 2018 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of the Trivial IP Encryption (TrIPE) Android app. + * + * TrIPE is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * TrIPE is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with TrIPE. If not, see . + */ + +package uk.org.distorted.tripe; package object progress; + +/*----- Imports -----------------------------------------------------------*/ + +import Math.ceil; +import System.currentTimeMillis; +import System.{err => stderr}; // FIXME: split out terminal progress + +/*----- Main code ---------------------------------------------------------*/ + +def formatTime(t: Int): String = + if (t < -1) "???" + else { + val (s, t1) = (t%60, t/60); + val (m, h) = (t1%60, t1/60); + if (h > 0) f"$h%d:$m%02d:$s%02d" + else f"$m%02d:$s%02d" + } + +private val UDATA = Seq("kB", "MB", "GB", "PB", "EB"); +def formatBytes(n: Long): String = { + val (x, u) = (n.toDouble, "B ") /: UDATA { + case ((x, u), name) if x >= 1024.0 => (x/1024.0, name) + case (xu, _) => xu + } + f"$x%6.1f$u%s" +} + +trait Eyecandy { + def set(line: String); + def clear(); + def commit(); + def commit(line: String) { commit(); set(line); commit(); } + + def begin(job: Job); +} + + +trait Job with Publisher[ { + def what: String; // imperative for what we're doing + def cur: Long; // current position in work + def max: Long; // maximum work to do + def format: String; // describe progress in useful terms + + private[this] val t0 = currentTimeMillis; + + def eta: Int = + /* Report the estimated time remaining in seconds, or -1 if no idea. + * + * The model here is very stupid. Weird jobs should override this and do + * something more sensible. + */ + + if (max < 0 || cur <= 0) -1 + else ceil((currentTimeMillis - t0)/1000.0 * + (max - cur)/cur.toDouble).toInt; +} + +object TerminalEyecandy extends Eyecandy { + private var last = ""; + var eyecandyp = + +} + +/*----- That's all, folks -------------------------------------------------*/