OpenSecurity/bin/download-image.pyw
author Oliver Maurhart <oliver.maurhart@ait.ac.at>
Wed, 29 Oct 2014 15:18:22 +0100
changeset 240 d7ef04254e9c
parent 86 a169498c5314
permissions -rwxr-xr-x
lizenz fixed in all files
oliver@83
     1
#!/bin/env python
oliver@83
     2
# -*- coding: utf-8 -*-
oliver@83
     3
oliver@83
     4
# ------------------------------------------------------------
oliver@83
     5
# download-osec-vm-image 
oliver@83
     6
# 
oliver@83
     7
# download the initial OsecVM.ova image
oliver@83
     8
#
oliver@240
     9
# Copyright 2013-2014 X-Net and AIT Austrian Institute of Technology
oliver@83
    10
# 
oliver@83
    11
# 
oliver@240
    12
#     X-Net Services GmbH
oliver@240
    13
#     Elisabethstrasse 1
oliver@240
    14
#     4020 Linz
oliver@240
    15
#     AUSTRIA
oliver@240
    16
#     https://www.x-net.at
oliver@240
    17
# 
oliver@240
    18
#     AIT Austrian Institute of Technology
oliver@240
    19
#     Donau City Strasse 1
oliver@240
    20
#     1220 Wien
oliver@240
    21
#     AUSTRIA
oliver@240
    22
#     http://www.ait.ac.at
oliver@240
    23
# 
oliver@240
    24
# 
oliver@240
    25
# Licensed under the Apache License, Version 2.0 (the "License");
oliver@240
    26
# you may not use this file except in compliance with the License.
oliver@240
    27
# You may obtain a copy of the License at
oliver@240
    28
# 
oliver@240
    29
#    http://www.apache.org/licenses/LICENSE-2.0
oliver@240
    30
# 
oliver@240
    31
# Unless required by applicable law or agreed to in writing, software
oliver@240
    32
# distributed under the License is distributed on an "AS IS" BASIS,
oliver@240
    33
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
oliver@240
    34
# See the License for the specific language governing permissions and
oliver@240
    35
# limitations under the License.
oliver@83
    36
# ------------------------------------------------------------
oliver@83
    37
oliver@83
    38
oliver@83
    39
# ------------------------------------------------------------
oliver@83
    40
# imports
oliver@83
    41
oliver@86
    42
import errno
oliver@83
    43
import os
oliver@83
    44
import sys
oliver@83
    45
import urllib2
oliver@83
    46
oliver@83
    47
from PyQt4 import QtCore
oliver@83
    48
from PyQt4 import QtGui
oliver@83
    49
oliver@83
    50
# local
oliver@83
    51
from environment import Environment
oliver@83
    52
oliver@83
    53
oliver@83
    54
# ------------------------------------------------------------
oliver@86
    55
# global vars
oliver@86
    56
oliver@86
    57
oliver@86
    58
vm_path = os.path.normpath(os.path.join(sys.path[0], '..', 'vm'))
oliver@86
    59
oliver@86
    60
oliver@86
    61
# ------------------------------------------------------------
oliver@83
    62
# code
oliver@83
    63
oliver@83
    64
oliver@83
    65
class DownloadDialog(QtGui.QDialog):
oliver@83
    66
    
oliver@83
    67
    """Download the initial OsecVM image dialog."""
oliver@83
    68
oliver@83
    69
    def __init__(self, parent = None, flags = QtCore.Qt.WindowFlags(0)):
oliver@83
    70
        
oliver@83
    71
        # super call and widget init
oliver@83
    72
        super(DownloadDialog, self).__init__(parent, flags)
oliver@83
    73
        self.setWindowTitle('Download initial OpenSecurity VM image')
oliver@83
    74
        self.setup_ui()
oliver@83
    75
oliver@83
    76
        # setup download thread
oliver@83
    77
        self._downloader = Downloader()
oliver@83
    78
        self._downloader.downloaded.connect(self.downloader_update)
oliver@83
    79
        self._thread = QtCore.QThread()
oliver@83
    80
        self._downloader.moveToThread(self._thread)
oliver@83
    81
        self._downloader.finished.connect(self._thread.quit)
oliver@83
    82
        self._thread.started.connect(self._downloader.work)
oliver@83
    83
        self._thread.finished.connect(self.finished_downloader)
oliver@83
    84
        self._thread.start() 
oliver@83
    85
oliver@83
    86
oliver@83
    87
    def clicked_cancel(self):
oliver@83
    88
oliver@83
    89
        """button cancel clicked"""
oliver@83
    90
oliver@83
    91
        # tell download thread to stop
oliver@83
    92
        self._downloader.stop = True
oliver@83
    93
oliver@83
    94
oliver@83
    95
    def downloader_update(self, current, total):
oliver@83
    96
        
oliver@83
    97
        """New download values present"""
oliver@83
    98
        if self.pbDownload.minimum() != 0:
oliver@83
    99
            self.pbDownload.setMinimum(0)
oliver@83
   100
        if self.pbDownload.maximum() != total:
oliver@83
   101
            self.pbDownload.setMaximum(total)
oliver@83
   102
        self.pbDownload.setValue(current)
oliver@83
   103
oliver@83
   104
oliver@83
   105
    def finished_downloader(self):
oliver@83
   106
        
oliver@83
   107
        """Download thread has finished (either success or abort)"""
oliver@83
   108
        if not self._downloader.error is None:
oliver@83
   109
            QtGui.QMessageBox.critical(None, 'OpenSecurity Download VM image error', self._downloader.error)
oliver@83
   110
oliver@83
   111
        self.accept();
oliver@83
   112
oliver@83
   113
oliver@83
   114
    def setup_ui(self):
oliver@83
   115
        
oliver@83
   116
        """Create the widgets."""
oliver@83
   117
        
oliver@83
   118
        lyMain = QtGui.QVBoxLayout(self)
oliver@83
   119
        lyMain.setContentsMargins(8, 8, 8, 8)
oliver@83
   120
oliver@83
   121
        lbTitle = QtGui.QLabel('Downloading OpenSecurity VM image')
oliver@83
   122
        lyMain.addWidget(lbTitle)
oliver@83
   123
        self.pbDownload = QtGui.QProgressBar()
oliver@83
   124
        self.pbDownload.setTextVisible(True)
oliver@83
   125
        lyMain.addWidget(self.pbDownload)
oliver@83
   126
       
oliver@83
   127
        # buttons
oliver@83
   128
        lyButton = QtGui.QHBoxLayout()
oliver@83
   129
        lyMain.addLayout(lyButton)
oliver@83
   130
        
oliver@83
   131
        lyButton.addStretch(1)
oliver@83
   132
        btnCancel = QtGui.QPushButton('&Cancel', self)
oliver@83
   133
        btnCancel.setMinimumWidth(100)
oliver@83
   134
        lyButton.addWidget(btnCancel)
oliver@83
   135
        
oliver@83
   136
        # connectors
oliver@83
   137
        btnCancel.clicked.connect(self.clicked_cancel)
oliver@83
   138
        
oliver@83
   139
        # reduce to the max
oliver@83
   140
        self.setMinimumWidth(400)
oliver@83
   141
        self.resize(lyMain.minimumSize())
oliver@83
   142
oliver@83
   143
oliver@83
   144
class Downloader(QtCore.QObject):
oliver@83
   145
oliver@83
   146
    """This is the worker thread when downloading"""
oliver@83
   147
oliver@83
   148
    downloaded = QtCore.pyqtSignal(int, int)
oliver@83
   149
    finished = QtCore.pyqtSignal()
oliver@83
   150
oliver@83
   151
    def __init__(self):
oliver@83
   152
        
oliver@83
   153
        # super call 
oliver@83
   154
        super(Downloader, self).__init__()
oliver@83
   155
        self.error = None
oliver@83
   156
        self.stop = False
oliver@83
   157
oliver@83
   158
        # place to store the OsecVM image
oliver@86
   159
        if not os.path.exists(vm_path):
oliver@86
   160
            os.mkdir(vm_path)
oliver@83
   161
 
oliver@83
   162
       
oliver@83
   163
    def work(self):
oliver@83
   164
oliver@83
   165
        """Thread method: download until finished or stopped"""
oliver@83
   166
oliver@83
   167
        url = "http://service.x-net.at/opensecurity/OsecVM_latest.ova"
oliver@83
   168
oliver@86
   169
        filename_download = os.path.join(vm_path, 'OsecVM_latest.ova')
oliver@86
   170
        filename_target = os.path.join(vm_path, 'OsecVM.ova')
oliver@83
   171
oliver@83
   172
        # open URL
oliver@83
   173
        try: 
oliver@83
   174
            resp = urllib2.urlopen(url)
oliver@83
   175
        except urllib2.URLError as e:
oliver@83
   176
            self.error = 'URLError: ' + str(e.reason)
oliver@83
   177
            self.finished.emit()
oliver@83
   178
            return
oliver@83
   179
        except urllib2.HTTPError as e:
oliver@83
   180
            self.error = 'HTTPError: ' + str(e.reason)
oliver@83
   181
            self.finished.emit()
oliver@83
   182
            return
oliver@83
   183
oliver@83
   184
        # download a CHUNK of data and then update the GUI
oliver@83
   185
        totalSize = int(resp.info().getheader('Content-Length').strip())
oliver@83
   186
        currentSize = 0
oliver@83
   187
        CHUNK_SIZE = 32768
oliver@83
   188
        self.downloaded.emit(currentSize, totalSize)
oliver@83
   189
oliver@83
   190
        f = open(filename_download, 'w')
oliver@83
   191
        while (not self.stop) and (currentSize < totalSize):
oliver@83
   192
            data = resp.read(CHUNK_SIZE)
oliver@83
   193
            currentSize += len(data)
oliver@83
   194
            f.write(data)
oliver@83
   195
            self.downloaded.emit(currentSize, totalSize)
oliver@83
   196
oliver@83
   197
        f.flush()
oliver@83
   198
        f.close()
oliver@83
   199
oliver@83
   200
        # rename the download to OsecVM.ova
oliver@83
   201
        if os.path.exists(filename_target):
oliver@83
   202
            os.remove(filename_target)
oliver@83
   203
        os.rename(filename_download, filename_target)
oliver@83
   204
oliver@83
   205
        self.finished.emit()
oliver@83
   206
oliver@83
   207
oliver@83
   208
def main():
oliver@83
   209
oliver@83
   210
    """entry point"""
oliver@83
   211
    
oliver@83
   212
    # launch Qt
oliver@83
   213
    global app
oliver@83
   214
    app = QtGui.QApplication(sys.argv)
oliver@83
   215
oliver@83
   216
    # prebuild the pixmap cache: fetch all jpg, png and jpeg images and load them
oliver@83
   217
    image_path = os.path.join(sys.path[0], '..', 'gfx')
oliver@83
   218
    for file in os.listdir(image_path):
oliver@83
   219
        if file.lower().rpartition('.')[2] in ('jpg', 'png', 'jpeg'):
oliver@83
   220
            QtGui.QPixmapCache.insert(file.lower().rpartition('.')[0], QtGui.QPixmap(os.path.join(image_path, file)))
oliver@83
   221
            
oliver@83
   222
    # we should have now our application icon
oliver@83
   223
    app.setWindowIcon(QtGui.QIcon(QtGui.QPixmapCache.find('opensecurity_icon_64')))
oliver@83
   224
oliver@86
   225
    # check essential permissions
oliver@86
   226
    try:
oliver@86
   227
        f = open(os.path.join(vm_path, '.x'), 'w')
oliver@86
   228
        f.write('test')
oliver@86
   229
        f.flush()
oliver@86
   230
        f.close()
oliver@86
   231
        os.remove(os.path.join(vm_path, '.x'))
oliver@86
   232
    except IOError as e:
oliver@86
   233
        if e.errno == errno.EACCES:
oliver@86
   234
            QtGui.QMessageBox.critical(None, 'OpenSecurity Download VM image error', 'No write access to "' + str(vm_path) + '"\nIs this run as Administrator?')
oliver@86
   235
            sys.exit(1)
oliver@86
   236
        else:
oliver@86
   237
            QtGui.QMessageBox.critical(None, 'OpenSecurity Download VM image error', 'Error occured.\nErrno: ' + str(e.errno))
oliver@86
   238
            sys.exit(1)
oliver@86
   239
oliver@86
   240
    # open download dialog
oliver@83
   241
    w = DownloadDialog()
oliver@83
   242
    w.show()
oliver@83
   243
oliver@83
   244
    # on with the show
oliver@83
   245
    sys.exit(app.exec_())
oliver@83
   246
   
oliver@83
   247
    
oliver@83
   248
# start
oliver@83
   249
if __name__ == "__main__":
oliver@83
   250
    main()
oliver@83
   251