2 # -*- coding: utf-8 -*-
4 # ------------------------------------------------------------
7 # let the user configure the opensecurity system
9 # Autor: Oliver Maurhart, <oliver.maurhart@ait.ac.at>
11 # Copyright (C) 2014 AIT Austrian Institute of Technology
12 # AIT Austrian Institute of Technology GmbH
13 # Donau-City-Strasse 1 | 1220 Vienna | Austria
14 # http://www.ait.ac.at
16 # This program is free software; you can redistribute it and/or
17 # modify it under the terms of the GNU General Public License
18 # as published by the Free Software Foundation version 2.
20 # This program is distributed in the hope that it will be useful,
21 # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 # GNU General Public License for more details.
25 # You should have received a copy of the GNU General Public License
26 # along with this program; if not, write to the Free Software
27 # Foundation, Inc., 51 Franklin Street, Fifth Floor,
28 # Boston, MA 02110-1301, USA.
29 # ------------------------------------------------------------
32 # ------------------------------------------------------------
35 # This script uses a QTimer (in a busy loop) for checking
36 # changes to the log file watched.
38 # Yes, this is sure f--g ugly.
40 # Thing is: there is no real good cross-platform in
41 # doing this nicely. And here we solve this problem
42 # neither. See doc in update_progress method.
44 # There is no python native but external packages
45 # using pip with different qualities (and struggling).
47 # Qt and as such PyQt offer the QFileSystemWatcher class
48 # which *could* solve this isse but
50 # a) this class is somehow buggy and unstable
51 # b) deprecated as of Qt 5.1
53 # ... and this ain't a beauty contest either, is it?
54 # ------------------------------------------------------------
57 # ------------------------------------------------------------
66 from PyQt4 import QtCore
67 from PyQt4 import QtGui
69 from ui_ConfigureDialog import Ui_ConfigureDialog
70 from about_dialog import AboutDialog
73 # ------------------------------------------------------------
77 class ConfigureDialog(QtGui.QDialog):
79 """A dialog which lets the user configure the OpenSecurity Subsystem"""
83 QtGui.QDialog.__init__(self)
85 # setup the user interface
86 self.ui = Ui_ConfigureDialog()
89 # monospace font fix for windows systems
90 font = QtGui.QFont("Monospace [Courier]")
92 font.setStyleHint(QtGui.QFont.TypeWriter)
93 font.setStyleStrategy(QtGui.QFont.PreferAntialias)
94 self.ui.edtProgress.setFont(font)
95 self.ui.edtLog.setFont(font)
97 self.ui.edtStatus.setText('<not evaluated yet>')
98 self.ui.edtVersion.setText('<not evaluated yet>')
99 self.ui.edtStatus.setEnabled(False);
100 self.ui.edtVersion.setEnabled(False);
103 self._about_dialog = AboutDialog()
104 self._file_watched_name = ''
105 self._file_watched_size = 0
106 self._file_watcher = QtCore.QTimer(self)
107 self._service_log_file = ''
108 self._service_log_size = 0
111 self.ui.btnAbout.clicked.connect(self.clicked_about)
112 self.ui.btnClose.clicked.connect(self.accept)
113 self.ui.btnDownload.clicked.connect(self.clicked_download)
114 self.ui.btnExplorer.clicked.connect(self.clicked_explorer)
115 self.ui.btnImport.clicked.connect(self.clicked_import)
116 self.ui.btnRefresh.clicked.connect(self.clicked_refresh)
117 self._file_watcher.timeout.connect(self.update_progress)
119 # call first refresh immediately
120 QtCore.QTimer.singleShot(0, self.clicked_refresh)
121 self._file_watcher.start(100)
124 def clicked_about(self):
126 """About button has been clicked."""
127 self._about_dialog.exec_()
130 def clicked_download(self):
132 """Download button has been clicked."""
135 self._file_watched_name = ''
136 self._file_watched_size = 0
137 self.ui.edtProgress.clear()
141 # get general server info
142 j = json.load(urllib2.urlopen('http://127.0.0.1:8080/fetch_initial_image'))
143 self._file_watched_name = str(j['fetch_log'])
149 def clicked_explorer(self):
151 """Explorer button has been clicked."""
152 if sys.platform == 'win32' or sys.platform == 'cygwin':
153 subprocess.Popen([os.path.join(os.environ['WINDIR'], 'explorer.exe'), self._service_log_path])
156 def clicked_import(self):
158 """Import button has been clicked."""
161 self._file_watched_name = ''
162 self._file_watched_size = 0
163 self.ui.edtProgress.clear()
167 # get general server info
168 j = json.load(urllib2.urlopen('http://127.0.0.1:8080/init'))
169 self._file_watched_name = str(j['init_log'])
175 def clicked_refresh(self):
177 """Refresh button has been clicked."""
178 self.ui.edtStatus.setText('<not evaluated yet>')
179 self.ui.edtVersion.setText('<not evaluated yet>')
180 self.ui.edtStatus.setEnabled(False);
181 self.ui.edtVersion.setEnabled(False);
182 self.ui.tvTemplate.clear()
183 self.ui.tvMachines.clear()
187 # get general server info
188 j = json.load(urllib2.urlopen('http://127.0.0.1:8080'))
189 self.ui.edtStatus.setText(j['os_server']['status message'])
190 self.ui.edtStatus.setEnabled(True)
191 self.ui.edtVersion.setText(j['os_server']['version'])
192 self.ui.edtVersion.setEnabled(True)
193 self._service_log_path = j['os_server']['current log folder']
194 self._service_log_file = os.path.join(self._service_log_path, 'OpenSecurity.log')
195 self._service_log_size = 0
197 # get initial template info
198 j = json.load(urllib2.urlopen('http://127.0.0.1:8080/initial_image'))
199 i = QtGui.QTreeWidgetItem(self.ui.tvTemplate)
200 i.setText(0, j['initial_template']['name'])
201 i.setText(1, QtCore.QDateTime.fromTime_t(int(j['initial_template']['date'])).toString(QtCore.Qt.SystemLocaleShortDate))
202 i.setText(2, str(j['initial_template']['size']))
203 i.setText(3, j['initial_template']['path'])
206 j = json.load(urllib2.urlopen('http://127.0.0.1:8080/vms'))
208 i = QtGui.QTreeWidgetItem(self.ui.tvMachines)
215 def update_progress(self):
217 """Our log file has changed, update ui"""
219 # we could use os.stat(PATH).st_mtime ...
221 # ... but Windows does not update it frequently. -.-
223 # Running a Cygwin Bash Shell script in the background
224 # does not update mtime of the redirected stderr file.
228 # first the service log
229 if self._service_log_file != '':
230 file_size = os.stat(self._service_log_file).st_size
231 if file_size > self._service_log_size:
232 f = open(self._service_log_file, 'r')
233 f.seek(self._service_log_size)
234 self.ui.edtLog.appendPlainText(f.read())
235 self._service_log_size = file_size
237 # now any processing log (download or import)
238 if self._file_watched_name == '':
241 file_size = os.stat(self._file_watched_name).st_size
242 if self._file_watched_size >= file_size:
245 f = open(self._file_watched_name, 'r')
246 self.ui.edtProgress.setPlainText(f.read())
247 self.ui.edtProgress.verticalScrollBar().setValue(self.ui.edtProgress.verticalScrollBar().maximum())
248 self._file_watched_size = file_size
251 if __name__ == "__main__":
252 a = QtGui.QApplication(sys.argv)
253 d = ConfigureDialog()