forked from IPKM/nmreval
crude updater added; write_state uses plain text, not pickle; disallow invalid characters; T246
This commit is contained in:
@ -37,7 +37,6 @@ class GraceMsgBox(QtWidgets.QDialog):
|
||||
agr.parse(fname)
|
||||
|
||||
layout = QtWidgets.QGridLayout()
|
||||
layout.setContentsMargins(13, 13, 13, 13)
|
||||
self.setLayout(layout)
|
||||
|
||||
label = QtWidgets.QLabel('%s already exists. Select one of the options or cancel:' % os.path.split(fname)[1])
|
||||
@ -100,9 +99,9 @@ class GeneralConfiguration(QtWidgets.QDialog):
|
||||
for key, value in parser.items(sec):
|
||||
label = QtWidgets.QLabel(key.capitalize(), self)
|
||||
layout2.addWidget(label, row, 0)
|
||||
if (sec, key) in allowed_values:
|
||||
if (sec, key) in ALLOWED_VALUE:
|
||||
edit = QtWidgets.QComboBox(self)
|
||||
edit.addItems(allowed_values[(sec, key)])
|
||||
edit.addItems(ALLOWED_VALUE[(sec, key)])
|
||||
edit.setCurrentIndex(edit.findText(value))
|
||||
else:
|
||||
edit = QtWidgets.QLineEdit(self)
|
||||
|
@ -1,8 +1,15 @@
|
||||
import sys
|
||||
from os import getenv, stat
|
||||
import hashlib
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
from contextlib import contextmanager
|
||||
|
||||
import requests
|
||||
from numpy import linspace
|
||||
from scipy.interpolate import interp1d
|
||||
|
||||
from ..Qt import QtGui, QtWidgets, QtCore
|
||||
from gui_qt.Qt import QtGui, QtWidgets, QtCore
|
||||
|
||||
|
||||
@contextmanager
|
||||
@ -48,3 +55,162 @@ class RdBuCMap:
|
||||
col = QtGui.QColor.fromRgb(*(float(self.spline[i](val)) for i in range(3)))
|
||||
|
||||
return col
|
||||
|
||||
|
||||
class UpdateDialog(QtWidgets.QDialog):
|
||||
host = 'mirror.infra.pkm'
|
||||
bucket = 'nmreval'
|
||||
version = 'NMReval-latest-x86_64'
|
||||
|
||||
def __init__(self, filename: str = None, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
self._init_ui()
|
||||
|
||||
if filename is None:
|
||||
filename = getenv('APPIMAGE')
|
||||
self._appfile = filename
|
||||
self._url_zsync = f'http://{self.host}/{self.bucket}/{self.version}.AppImage.zsync'
|
||||
|
||||
self.process = QtCore.QProcess(self)
|
||||
|
||||
self.look_for_updates()
|
||||
|
||||
def _init_ui(self):
|
||||
self.setWindowTitle('Updates')
|
||||
|
||||
layout = QtWidgets.QVBoxLayout()
|
||||
|
||||
self.label = QtWidgets.QLabel()
|
||||
layout.addWidget(self.label)
|
||||
|
||||
layout.addSpacing(10)
|
||||
|
||||
self.dialog_button = QtWidgets.QDialogButtonBox()
|
||||
self.dialog_button.accepted.connect(self.accept)
|
||||
self.dialog_button.rejected.connect(self.reject)
|
||||
layout.addWidget(self.dialog_button)
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
def look_for_updates(self):
|
||||
# Download zsync file of latest Appimage, look for SHA-1 hash and compare with hash of AppImage
|
||||
m_time_zsync, checksum_zsync = self.get_zsync()
|
||||
m_time_file, checksum_file = self.get_appimage_info()
|
||||
|
||||
if m_time_zsync is None:
|
||||
label_text = '<p>Retrieval of version information failed.</p>' \
|
||||
'<p>Please try later (or complain to people that it does not work).</p>'
|
||||
dialog_bttns = QtWidgets.QDialogButtonBox.Close
|
||||
else:
|
||||
label_text = f'<p>Found most recent update: {m_time_zsync.strftime("%d %B %Y %H:%M")}</p>'
|
||||
|
||||
if m_time_file is None:
|
||||
label_text += 'No AppImage file found, press Ok to downlaod latest version.'
|
||||
dialog_bttns = QtWidgets.QDialogButtonBox.Ok|QtWidgets.QDialogButtonBox.Close
|
||||
else:
|
||||
label_text += f'<p>Date of used AppImage: {m_time_file.strftime("%d %B %Y %H:%M")}</p>'
|
||||
|
||||
if not ((checksum_file is not None) and (checksum_zsync is not None)):
|
||||
label_text += 'Could not determine if this version is newer, please update manually (if necessary).'
|
||||
dialog_bttns = QtWidgets.QDialogButtonBox.Close
|
||||
elif checksum_file != checksum_zsync:
|
||||
label_text += f'<p>Newer version available. <b>Update?</b></p>'
|
||||
dialog_bttns = QtWidgets.QDialogButtonBox.Ok|QtWidgets.QDialogButtonBox.Cancel
|
||||
else:
|
||||
label_text += f'<p>Version is already the newest</p>'
|
||||
dialog_bttns = QtWidgets.QDialogButtonBox.Close
|
||||
|
||||
self.label.setText(label_text)
|
||||
self.dialog_button.setStandardButtons(dialog_bttns)
|
||||
|
||||
def get_zsync(self):
|
||||
m_time_zsync = None
|
||||
checksum_zsync = None
|
||||
zsync_file = None
|
||||
try:
|
||||
response = requests.get(self._url_zsync)
|
||||
if response.status_code == requests.codes['\o/']:
|
||||
zsync_file = response.content
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
if zsync_file is not None:
|
||||
for line in zsync_file.split(b'\n'):
|
||||
try:
|
||||
kw, val = line.split(b': ')
|
||||
if kw == b'MTime':
|
||||
m_time_zsync = datetime.strptime(str(val, encoding='utf-8'), '%a, %d %b %Y %H:%M:%S %z').astimezone(None)
|
||||
elif kw == b'SHA-1':
|
||||
checksum_zsync = str(val, encoding='utf-8')
|
||||
|
||||
except ValueError:
|
||||
# stop when empty line is reached
|
||||
break
|
||||
|
||||
return m_time_zsync, checksum_zsync
|
||||
|
||||
def get_appimage_info(self):
|
||||
if self._appfile is None:
|
||||
return None, None
|
||||
|
||||
stat_mtime = stat(self._appfile).st_mtime
|
||||
m_time_file = datetime.fromtimestamp(stat_mtime).replace(microsecond=0)
|
||||
with open(self._appfile, 'rb') as f:
|
||||
checksum_file = hashlib.sha1(f.read()).hexdigest()
|
||||
|
||||
return m_time_file, checksum_file
|
||||
|
||||
def update_appimage(self):
|
||||
if self._appfile is None:
|
||||
args = [self._url_zsync]
|
||||
else:
|
||||
args = ['-i', self._appfile, self._url_zsync]
|
||||
|
||||
self.process.readyReadStandardOutput.connect(self.onReadyReadStandardOutput)
|
||||
self.process.readyReadStandardError.connect(self.onReadyReadStandardOutput)
|
||||
self.process.start('zsync', args)
|
||||
|
||||
if not self.process.waitForFinished():
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def onReadyReadStandardOutput(self):
|
||||
result = self.process.readAllStandardOutput().data().decode()
|
||||
self.label.setText(result)
|
||||
|
||||
|
||||
def accept(self):
|
||||
if self.update_appimage():
|
||||
_ = QtWidgets.QMessageBox.information(self, 'Updates', 'Download finished. Execute AppImage for new version.')
|
||||
super().accept()
|
||||
|
||||
|
||||
|
||||
def open_bug_report():
|
||||
form_entries = {
|
||||
'description': 'Please state the nature of the medical emergency.',
|
||||
'title': 'Everything is awesome?',
|
||||
'assign[0]': 'dominik',
|
||||
'subscribers[0]': 'dominik',
|
||||
'tag': 'nmreval',
|
||||
'priority': 'normal',
|
||||
'status': 'open',
|
||||
}
|
||||
full_url = 'https://chaos3.fkp.physik.tu-darmstadt.de/maniphest/task/edit/?'
|
||||
|
||||
for k, v in form_entries.items():
|
||||
full_url += f'{k}={v}&'
|
||||
full_url.replace(' ', '+')
|
||||
|
||||
import webbrowser
|
||||
webbrowser.open(full_url)
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = QtWidgets.QApplication([])
|
||||
w = UpdateDialog()
|
||||
w.show()
|
||||
|
||||
sys.exit(app.exec())
|
||||
|
Reference in New Issue
Block a user