Browse Source

qvm-template-gui: improve displaying progress

The final version of qvm-template does not display untrusted data, so it
is safe to decode UTF-8. Specifically, this shows download progress bar
done using tqdm library.
For this to work, \r needs to be properly handled, as tqdm uses it to
erase the current line to update progress status. Since QTextEdit does
not support it natively, add a simple wrapper for this job.
Alternatively, qvm-template could be modified to display
machine-readable progress info that would be passed through QT progress
widget, but it would basically duplicate the work already done by tqdm
library. We might do this at some point, though.

And also enlarge progress window default size, to avoid wrapping.
Marek Marczykowski-Górecki 3 years ago
parent
commit
03a34fbedd
2 changed files with 21 additions and 6 deletions
  1. 19 4
      qubesmanager/qvm_template_gui.py
  2. 2 2
      ui/templateinstallprogressdlg.ui

+ 19 - 4
qubesmanager/qvm_template_gui.py

@@ -15,7 +15,7 @@ from . import utils
 
 #pylint: disable=invalid-name
 
-BASE_CMD = ['qvm-template', '--enablerepo=*', '--yes', '--quiet']
+BASE_CMD = ['qvm-template', '--enablerepo=*', '--yes']
 
 class Template(typing.NamedTuple):
     status: str
@@ -291,6 +291,19 @@ class TemplateInstallProgressDialog(
         self.actions = actions
         self.buttonBox.hide()
 
+    @staticmethod
+    def _process_cr(text):
+        """Reduce lines replaced using CR character (\r)"""
+        while '\r' in text:
+            prefix, suffix = text.rsplit('\r', 1)
+            if '\n' in prefix:
+                prefix = prefix.rsplit('\n', 1)[0]
+                prefix += '\n'
+            else:
+                prefix = ''
+            text = prefix + suffix
+        return text
+
     def install(self):
         async def coro():
             self.actions.sort()
@@ -313,12 +326,14 @@ class TemplateInstallProgressDialog(
                     stderr=asyncio.subprocess.STDOUT,
                     env=envs)
                 #pylint: disable=cell-var-from-loop
+                status_text = ''
                 while True:
-                    line = await proc.stdout.readline()
+                    line = await proc.stdout.read(100)
                     if line == b'':
                         break
-                    line = line.decode('ASCII')
-                    self.textEdit.append(line.rstrip())
+                    line = line.decode('UTF-8')
+                    status_text = self._process_cr(status_text + line)
+                    self.textEdit.setPlainText(status_text)
                 if await proc.wait() != 0:
                     self.buttonBox.show()
                     self.progressBar.setMaximum(100)

+ 2 - 2
ui/templateinstallprogressdlg.ui

@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>400</width>
-    <height>300</height>
+    <width>840</width>
+    <height>260</height>
    </rect>
   </property>
   <property name="windowTitle">