A gui application used for interactive upgrade reminders on Debian. I no longer use it and will not push changes.
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 

189 wiersze
6.3 KiB

  1. #!/usr/bin/python3
  2. from PySide2.QtWidgets import (QApplication, QLabel,
  3. QPushButton, QSlider,
  4. QLineEdit, QWidget, QVBoxLayout, QHBoxLayout,
  5. QDialog, QGroupBox, QTabWidget, QErrorMessage,
  6. QListWidgetItem, QGridLayout, QTextEdit,
  7. QComboBox, QToolBar, QInputDialog, QAction,
  8. QStackedWidget, QTextBrowser)
  9. from PySide2.QtCore import (Qt, QThread, Signal, QDir, QProcess,
  10. QCoreApplication)
  11. from PySide2.QtGui import (QIcon, QMovie)
  12. import sys, subprocess, trio, io
  13. class UpdatePrompt(QDialog):
  14. def __init__(self):
  15. super().__init__()
  16. self.makeView()
  17. return
  18. def makeView(self):
  19. layout = QVBoxLayout()
  20. btnLayout = QHBoxLayout()
  21. self.centStack = QStackedWidget()
  22. updateButton = QPushButton('Update')
  23. cancelButton = QPushButton('Cancel')
  24. notifyLabel = QLabel('There are updates scheduled')
  25. self.inputBox = QLineEdit()
  26. self.outputBox = QTextBrowser()
  27. #refreshIcon = QIcon.fromTheme('process-working')
  28. self.refreshIcon = QMovie('assets/spin3.gif')
  29. refreshAnimation = QLabel()
  30. layout.addWidget(notifyLabel)
  31. layout.addWidget(self.centStack)
  32. layout.addWidget(self.inputBox)
  33. layout.addLayout(btnLayout)
  34. btnLayout.addWidget(cancelButton)
  35. btnLayout.addWidget(updateButton)
  36. self.centStack.addWidget(refreshAnimation)
  37. self.centStack.addWidget(self.outputBox)
  38. refreshAnimation.setMovie(self.refreshIcon)
  39. refreshAnimation.setAlignment(Qt.AlignCenter)
  40. self.refreshIcon.start()
  41. self.inputBox.setEchoMode(QLineEdit.Password)
  42. self.inputBox.setFocus()
  43. self.inputBox.returnPressed.connect(self.pkgUpdates)
  44. updateButton.clicked.connect(self.pkgUpdates)
  45. cancelButton.clicked.connect(self.cancelUpdates)
  46. self.centStack.setCurrentIndex(1)
  47. notifyLabel.setAlignment(Qt.AlignTop)
  48. self.outputBox.setReadOnly(True)
  49. #self.outputBox.setAlignment(Qt.AlignTop)
  50. self.setWindowTitle('Package Updates')
  51. self.setLayout(layout)
  52. self.resize(450, 250)
  53. return
  54. async def asetup(self, password):
  55. async with trio.open_nursery() as nursery:
  56. finishedState = trio.Event()
  57. nursery.start_soon(self.upProc, password, 'update', finishedState)
  58. #nursery.start_soon(self.KEAlive, finishedState)
  59. return
  60. async def upProc(self, password, cmd, finishedState):
  61. # proc = subprocess.Popen(['sudo', '-S', 'apt-get', cmd, '-y'],
  62. # stdout=subprocess.PIPE,
  63. # stderr=subprocess.STDOUT,
  64. # stdin=subprocess.PIPE)
  65. proc = await trio.open_process(['sudo', '-S', 'apt-get', cmd, '-y'],
  66. stdin=subprocess.PIPE, stdout=subprocess.PIPE,
  67. stderr=subprocess.STDOUT)
  68. await proc.stdin.send_all((password + '\n').encode())
  69. result = ''
  70. while (proc.poll() == None):
  71. QCoreApplication.processEvents()
  72. await trio.sleep(0.1)
  73. #a = await proc.stdout.receive_some()
  74. #a = a.decode()
  75. #print(a)
  76. #result = result + a
  77. #stdout = result.stdout.decode()
  78. result = await self.pullOutput(proc)
  79. self.appendToOutput(result)
  80. proc.terminate()
  81. if (cmd == 'update'):
  82. await self.upProc(password, 'upgrade', finishedState)
  83. finishedState.set()
  84. return
  85. async def pseudoSleep(self, intervals):
  86. i = 0
  87. return
  88. async def pullOutput(self, proc):
  89. x = await proc.stdout.receive_some()
  90. x = x.decode()
  91. result = ''
  92. while (x != ''):
  93. QCoreApplication.processEvents()
  94. result = result + x
  95. x = await proc.stdout.receive_some()
  96. x = x.decode()
  97. return result
  98. async def KEAlive(self, finishedState):
  99. while finishedState.is_set():
  100. QCoreApplication.processEvents()
  101. trio.sleep(0.1)
  102. return
  103. return
  104. def appendToOutput(self, add):
  105. currentText = self.outputBox.toPlainText()
  106. self.outputBox.setText(currentText + 'Running updates\n' + add + '\n')
  107. print (add)
  108. return
  109. def pkgUpdates(self):
  110. self.centStack.setCurrentIndex(0)
  111. self.refreshIcon.start()
  112. QCoreApplication.processEvents()
  113. password = self.inputBox.text()
  114. if (password == ''):
  115. self.passError('The password field cannot be empty')
  116. return
  117. # password = password.encode()
  118. # result = subprocess.run(['sudo', '-S', 'apt-get', 'update'],
  119. # stdout=subprocess.PIPE,
  120. # stderr=subprocess.STDOUT, input=password)
  121. # result = subprocess.run(['sudo', '-S', 'apt-get', 'upgrade', '-y'],
  122. # stdout=subprocess.PIPE,
  123. # stderr=subprocess.STDOUT, input=password)
  124. # stdout = result.stdout.decode()
  125. # currentText = self.outputBox.toPlainText()
  126. # self.outputBox.setText(currentText + '\nRunning upgrades\n' + stdout)
  127. # result = subprocess.run(['sudo', 'apt', 'upgrade', '-y'],
  128. # stdout=subprocess.PIPE,
  129. # stderr=subprocess.STDOUT, input=password)
  130. # currentText = self.outputBox.toPlainText()
  131. # self.outputBox.setText(currentText + '\n' + stdout)
  132. #self.refreshIcon.stop()
  133. trio.run(self.asetup, password)
  134. self.centStack.setCurrentIndex(1)
  135. self.refreshIcon.stop()
  136. return
  137. def passError(self, s):
  138. passError = QDialog(self)
  139. msg = QLabel(s)
  140. layout = QVBoxLayout()
  141. layout.addWidget(msg)
  142. passError.setLayout(layout)
  143. okBtn = QPushButton('OK')
  144. okBtn.clicked.connect(passError.reject)
  145. layout.addWidget(okBtn)
  146. passError.exec_()
  147. return
  148. def cancelUpdates(self):
  149. self.reject()
  150. return
  151. if __name__ == '__main__':
  152. app = QApplication([])
  153. view = UpdatePrompt()
  154. view.show()
  155. sys.exit(app.exec_())