Skip to content

Commit c022588

Browse files
committed
feat(www): add a circular progress indicator during upload
Signed-off-by: Cedric Hombourger <[email protected]>
1 parent ea8179d commit c022588

File tree

5 files changed

+39
-16
lines changed

5 files changed

+39
-16
lines changed

mtda-www

+5-1
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,17 @@ class StorageOpenHandler(BaseHandler):
158158
if mtda is not None:
159159
compr = CONSTS.IMAGE.RAW.value
160160
file = self.get_argument('file')
161+
try:
162+
size = int(self.get_argument('size', 0))
163+
except ValueError:
164+
size = 0
161165
if file:
162166
mtda.debug(2, f'file to be uploaded: {file}')
163167
compr = Compression.from_extension(file)
164168
mtda.storage_compression(compr)
165169

166170
sid = self.get_argument('session')
167-
zmq_socket = mtda.storage_open(session=sid)
171+
zmq_socket = mtda.storage_open(size, session=sid)
168172
self.application.settings['sockets'][sid] = zmq_socket
169173

170174
self.result_as_json({"result": result})

mtda/client.py

+9-6
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,14 @@ def storage_network(self, remote):
123123
cmd = ['sudo', cmd_nbd, '-N', 'mtda-storage', remote]
124124
subprocess.check_call(cmd)
125125

126-
def storage_open(self, **kwargs):
126+
def storage_open(self, size=0, **kwargs):
127127
session = kwargs.get('session', None)
128128
tries = 60
129129
while tries > 0:
130130
tries = tries - 1
131131
try:
132132
host = self.remote()
133-
port = self._impl.storage_open(session=session)
133+
port = self._impl.storage_open(size, session=session)
134134
context = zmq.Context()
135135
socket = context.socket(zmq.PUSH)
136136
hwm = int(
@@ -168,7 +168,7 @@ def storage_update(self, dest, src=None, callback=None):
168168
file = ImageFile.new(path, impl, session, blksz, callback)
169169

170170
# Open the shared storage device so we own it
171-
self.storage_open()
171+
self.storage_open(image_size)
172172

173173
try:
174174
# Prepare for download/copy
@@ -198,7 +198,7 @@ def storage_write_image(self, path, callback=None):
198198
# Open the shared storage device so we own it
199199
# It also prevents us from loading a new bmap file while
200200
# another transfer may be on-going
201-
self.storage_open()
201+
self.storage_open(file.size)
202202

203203
# Automatically discover the bmap file
204204
bmap = None
@@ -356,7 +356,7 @@ def prepare(self, socket, output_size=None, compression=None):
356356
compr = None
357357
if compression is None:
358358
compr = Compression.from_extension(self._path)
359-
self._inputsize = self.size()
359+
self._inputsize = self.size
360360
self._outputsize = output_size
361361
self._socket = socket
362362
# if image is uncompressed, we compress on the fly
@@ -378,8 +378,9 @@ def progress(self):
378378
callback(imgname, totalread, inputsize, written, outputsize)
379379
self._lastreport = time.time()
380380

381+
@property
381382
def size(self):
382-
return None
383+
return 0
383384

384385
def _write_to_storage(self, data):
385386
self._socket.send(data)
@@ -424,6 +425,7 @@ def copy(self):
424425
else:
425426
image.close()
426427

428+
@property
427429
def size(self):
428430
st = os.stat(self._path)
429431
return st.st_size
@@ -476,6 +478,7 @@ def copy(self):
476478
config = TransferConfig(use_threads=False)
477479
self._object.download_fileobj(self, Config=config)
478480

481+
@property
479482
def size(self):
480483
if self._object is None:
481484
self._object = self._open()

mtda/main.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,7 @@ def storage_network(self, **kwargs):
848848
return result
849849

850850
@Pyro4.expose
851-
def storage_open(self, stream=None, **kwargs):
851+
def storage_open(self, size=0, stream=None, **kwargs):
852852
self.mtda.debug(3, 'main.storage_open()')
853853

854854
result = None
@@ -876,7 +876,7 @@ def storage_open(self, stream=None, **kwargs):
876876
if stream is None:
877877
from mtda.storage.datastream import NetworkDataStream
878878
stream = NetworkDataStream(self.dataport)
879-
result = self._writer.start(session, stream)
879+
result = self._writer.start(session, size, stream)
880880

881881
self.mtda.debug(3, f'main.storage_open(): {result}')
882882
return result

mtda/storage/writer.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,11 @@ def flush(self, size):
9797
self.mtda.debug(3, f"storage.writer.flush(): {result}")
9898
return result
9999

100-
def start(self, session, stream):
100+
def start(self, session, size, stream):
101101
self.mtda.debug(3, "mtda.storage.writer.start()")
102102

103103
self._session = session
104+
self._size = size
104105
self._stream = stream
105106

106107
result = stream.prepare()
@@ -155,7 +156,7 @@ def worker(self):
155156
if (now - last_notification) >= CONSTS.WRITER.NOTIFY_SECONDS:
156157
speed = (received - last_read) / (now - last_notification)
157158
mtda._storage_event(f'{CONSTS.STORAGE.WRITING} '
158-
f'{received} {speed}')
159+
f'{received} {self._size} {speed}')
159160
last_notification = now
160161
last_read = received
161162

mtda/templates/index.html

+20-5
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,16 @@
113113
hidden: true
114114
});
115115
xferWindow = new WinBox("Transferring", {
116-
html: "<canvas id='xferCanvas' width='320' height='200'></canvas>",
116+
html: "<svg width='100' height='100' viewBox='0 0 100 100'>" +
117+
"<circle cx='50' cy='50' r='40' stroke='#eee' stroke-width='8' fill='none'/>" +
118+
"<circle id='xferProgress' cx='50' cy='50' r='40' stroke='#00aaff' stroke-width='8' fill='none'" +
119+
"stroke-dasharray='251.2' stroke-dashoffset='251.2' stroke-linecap='round'/>" +
120+
"<text id='xferPercent' x='50' y='55' font-size='16' text-anchor='middle' fill='#333'>0%</text>" +
121+
"</svg>" +
122+
"<canvas id='xferCanvas' width='220' height='100'></canvas>",
117123
class: ["no-full", "no-max", "modern"],
118-
width: "320px",
119-
height: "200px",
124+
width: "360px",
125+
height: "150px",
120126
hidden: true
121127
});
122128
var xferChart;
@@ -203,6 +209,7 @@
203209
$('#upload').bind('click', function() {
204210
$.getJSON('./storage-open', {
205211
file: selectedFile.name,
212+
size: selectedFile.size,
206213
session: localStorage.getItem('session')
207214
}, function(data) {
208215
// do nothing
@@ -328,7 +335,15 @@
328335
}
329336
break;
330337
case 'WRITING':
331-
let speed = args[1] / 1024 / 1024;
338+
var percent = 0;
339+
let read = args[0];
340+
let size = args[1];
341+
let speed = args[2] / 1024 / 1024;
342+
if (size) {
343+
percent = Math.round((read * 100) / size);
344+
$("#xferProgress").css("stroke-dashoffset", 251.2 - (percent / 100) * 251.2);
345+
$("#xferPercent").text(percent + "%");
346+
}
332347
if (xferWindow.hidden) {
333348
uploadWindow.hide();
334349
xferWindow.move('center', 'center');
@@ -339,7 +354,7 @@
339354
millisPerPixel: 100,
340355
maxValueScale: 1.2,
341356
minValueScale: 1.2,
342-
grid: { strokeStyle: 'rgba(0, 0, 0, 0.2)', verticalSections: 4 },
357+
grid: { fillStyle: 'rgba(40, 40, 40, 0.2)', strokeStyle: 'rgba(90, 90, 90, 0.2)', verticalSections: 4 },
343358
});
344359
xferChart.streamTo(document.getElementById("xferCanvas"), 1000);
345360
xferChart.addTimeSeries(xferSeries, { strokeStyle: 'rgb(0, 255, 0)', lineWidth: 2 });

0 commit comments

Comments
 (0)