Exemplo n.º 1
0
def __CleanUpArchiveFiles(fileList):
    '''
    Cleanup durchführen, von Dateien die zwar für den Upload erstellt wurden wie z.B. Plots, aber
    nach dem Zippen nun nicht mehr benötigt werden.
    @param fileList: Dict mit den Dateien, welche im ZIP hinterlegt wurden und nun ggf. gelöscht
                     werden können.
    @type fileList: dict
    '''
    for each in fileList:
        if each.get(u"removeFileAfterZipped", False):
            toRemove = each.get(u'file')
            try:
                if toRemove is not None and os.path.exists(toRemove):
                    os.remove(toRemove)

                    # Leere erstellte Parent-Ordner löschen (maximal zwei Ebenen nach oben!)
                    parentRemoveCounter = 0
                    tmpDir = os.path.dirname(toRemove)
                    while (parentRemoveCounter < 2):
                        parentRemoveCounter += 1
                        shutil.rmtree(tmpDir, True)
                        # Nächstes Parent ermitteln
                        tmpDir = os.path.dirname(tmpDir)

            except BaseException as ex:
                EPrint(
                    _(u"Löschen der Datei {0} nicht möglich: {1}").format(
                        toRemove, ex))
Exemplo n.º 2
0
def FilterShortName(shortName):
    '''
    Entfernt unerlaubte Sonderzeichen aus dem übergebenen String und ersetzt diese ggf. mit
    einem Unterstrich "_".
    Anschließend werden Unterstriche am Anfang und Ende des Strings entfernt.
    @param shortName: zu filternder String.
    @type shortName: str
    @return: bereinigter String.
    @rtype: str
    '''
    converter = PackageNameToATXTestCaseShortName()
    validShortname = converter.GetValidShortName(shortName)

    # Wenn der Shortname länger ist als die erlaubten 128 Zeichen (PlannedFolder _XY Zusatz-Counter
    # bedenken), dann als Fallback versuchen den Namen zu kürzen indem mögliche Unterstriche
    # komplett entfernt werden.
    maxLength = 128 - 3
    if len(validShortname) > maxLength:
        validShortname = AutoShortnameUnderscoreCut(validShortname, maxLength)

        if len(validShortname) <= maxLength:
            WPrint(_(u"Maximale Länge von 125 Zeichen beim ATX-Name '{0}' überschritten. "
                     u"Der Name wurde automatisch gekürzt durch das Entfernen von Unterstrichen").
                   format(shortName))

    if len(validShortname) > maxLength:
        EPrint(_(u"ATX-Name '{0}' ist zu lang - erlaubt sind max. 125 Zeichen!").format(shortName))

    return validShortname
Exemplo n.º 3
0
def __AutoUpdate(atxReportTemplateDir, proxies, useHttps, hostUrl, port,
                 contextUrl, authKey):
    '''
    Lädt die passende ATX Version vom Server und entpackt diese in Templateverzeichnis des
    Workspaces und aktualisert dann nachfolgenden Module für die Weiterverarbeitung.
    @param atxReportTemplateDir: Verzeichnis in welchem der neue ATX-Generator liegen soll.
    @type atxReportTemplateDir: str
    @param proxies: Dict mit dem Mapping der Protokolle bei Verwendung eines Proxies
    @type proxies: dict
    @param useHttps: True, wenn eine Https-Verbindung verwendet werden soll, sonst False.
    @type useHttps: boolean
    @param hostUrl: Haupt-URL
    @type hostUrl: str
    @param port: Port
    @type port: integer
    @param contextUrl: Context-URL (kann u.U. auch leer sein)
    @type contextUrl: str
    @param authKey: Authentifizierungsschlüssel für den Download
    @type authKey: str
    @return: True, wenn das AutoUpdate erfolgreich war, sonst False.
    @rtype: boolean
    '''
    # Nach erfolgreichem Download und entpacken die Module aktualisieren
    if __DownloadAndUnZipATXMakoInTemplateDir(atxReportTemplateDir, proxies,
                                              useHttps, hostUrl, port,
                                              contextUrl, authKey):
        # ReportManager aktualisieren
        from lib.report.ReportManager import ReportManager
        ReportManager().UpdateHandler()
        SPrint(_(u"ATX AutoUpdate ist erfolgt."))
        return True
    else:
        EPrint(_(u"ATX AutoUpdate fehlgeschlagen!"))
        return False
Exemplo n.º 4
0
    def __ComputePlotRefPaths(self, plots, rootNode, stepShortName):
        """
        Ermittelt zu den übergebenen Plots und dem TEST-STEP die Zuweisung der Dateien über den
        RefPath der TEST-STEPS.
        :param plots: Liste der Plot-Dateien, welche im TEST-STEP gefunden wurden.
        :type plots: list
        :param rootNode: Root-Node, welcher durchsucht werden solle
        :type rootNode: Node
        :param stepShortName: eindeutiger TEST-STEP Shortname zu welchem die Plots gesucht werden
                              sollen
        :type stepShortName: str
        """
        if len(plots) > 0:

            def GetRefTestStepPath(steps):
                """
                Ermittelt den RefPath des gesuchten TEST-STEP-Shortnames.
                :param steps: Liste mit den enthaltenen TEST-STEPS auf der Ebene
                :type steps: list
                :return: None oder den Ref-Path des TEST-STEPS.
                :rtype: str
                """
                result = None
                for eachStep in steps:
                    if eachStep[u'SHORT-NAME'] == stepShortName:
                        result = eachStep[u'ORIGIN-REF'][u'#']
                        break
                    else:
                        result = GetRefTestStepPath(
                            eachStep.get(u'*TEST-STEPS', []))
                return result

            refPath = GetRefTestStepPath(rootNode.GetList()[u'reportSteps'])
            if refPath is None:
                EPrint(u'Compute ORIGIN TEST-STEP RefPath failed!')
            else:
                if refPath not in self.__plots:
                    self.__plots[refPath] = []
                self.__plots[refPath].extend(plots)
Exemplo n.º 5
0
 def __GetXmlRoot(self, data):
     '''
     Erstellt den Root-Knoten der ATX-XML und hängt die Daten unterhalb des Root-Knotens an.
     @param data: Daten, welche als XML rausgeschrieben werden sollen.
     @type data: dict oder list
     @return: Root-Konten des ATX-XML Dokumentes
     @rtype: etree.Element
     '''
     try:
         root = etree.Element(
             u'ATX',
             nsmap={
                 u'xsi': u'http://www.w3.org/2001/XMLSchema-instance',
                 None: u'http://www.asam.net/schema/ATX/r1.0'
             })
         root.append(
             etree.Comment(u"Generator version: {0}".format(
                 self.__version)))
         self.__AddElements(root, data)
     except BaseException as ex:
         import traceback
         traceback.print_exc()
         EPrint(u"Error on: {0}: {1}".format(self.__reportTrfFile, ex))
     return root
Exemplo n.º 6
0
    def __AsyncUpload(self, response, startUploadTime, serverLabel):
        """
        Führt den asynchronen Upload durch. Es erfolgt ein Upload der Daten an TEST-GUIDE, welches
        dann die Status-URl des Uploads bereitstellt und hier direkt gepollt wird.
        :param response: HTTP-Antwort, für den verwendeten Upload.
        :type response: requests.Response
        :param startUploadTime: Startzeitpunkt des Uploads für die Messung und die Anzeige in der
                                Log-Anzeige.
        :type startUploadTime: datetime.datetime
        :param serverLabel: Server, der ausgewählt wurde für die Log-Anzeige.
        :type serverLabel: str
        :returns: True, bei erfolgreichem Upload, sonst False.
        :rtype: boolean
        """
        statusResLink = None

        visual = ShowInfoOnTaskManager(
            self.__reportApi, _(u'Upload wird asynchron verarbeitet...'))

        # Erwartete Rückgabe von TEST-GUIDE
        # {'ENTRIES':[{'FILE': 'file-upload6523204238481192334.tmp',
        #              'STATUS': 202,
        #              'TEXT': '/api/upload-file/status/6'}]}
        if response.status_code == 202:
            try:
                respDict = response.json()
            except Exception as err:
                EPrint(u'Read async upload payload failed: {0}'.format(
                    str(err)))
                respDict = {}

            responses = respDict.get(u'ENTRIES', [])
            if responses:
                statusResLink = responses.pop().get(u'TEXT')
        else:
            raise self._CreateUploadError(response.status_code,
                                          u'Upload status request failed')

        if statusResLink:
            statusUrl = self._GetStatusUrl(statusResLink)

            # Polling für die Status-Abfrage durchführen.
            constMinSleepTimeSec = 3
            constMaxWaitTimeHours = 7
            constMaxWaitTimeInSec = constMaxWaitTimeHours * 60 * 60

            waitTimeSec = 0
            while waitTimeSec < constMaxWaitTimeInSec:
                requestStat = requests.get(
                    url=statusUrl,
                    headers={
                        u'Accept':
                        u'application/{accept}'.format(accept=self.__accept)
                    },
                    verify=False,
                    proxies=self.__proxies)
                requestStat.raise_for_status()

                try:
                    respDict = requestStat.json()
                except ValueError as err:
                    EPrint(u'Read async upload status failed: {0}'.format(
                        str(err)))
                    respDict = {}

                status = respDict.get(u'status')
                if status == u'FINISHED':
                    statusCode = respDict.get(u'statusCode')

                    if statusCode >= 300:
                        raise UploadError(statusCode, u'Upload failed',
                                          respDict)
                    else:
                        self.__SuccessUpload(requestStat.content, statusCode,
                                             startUploadTime, serverLabel)
                        return True
                else:
                    statusMsg = respDict.get(u'lastCommandDescription')
                    if statusMsg and visual:
                        visual.SetCaption(
                            _(u'Uploadstatus: {0}').format(statusMsg))

                # Minimum-Wartezeit bis zur nächsten Abfrage
                time.sleep(constMinSleepTimeSec)
                waitTimeSec += constMinSleepTimeSec
        else:
            # Wenn der Statuslink nicht ermittelt werden kann!
            raise self._CreateUploadError(500, u'Unknown status link')

        return False
Exemplo n.º 7
0
    def StartUpload(self):
        """
        Führt den zuvor präparierten Upload aus.
        :returns: True bei Erfolg, sonst False.
        :rtype: boolean
        """
        startUploadTime = datetime.datetime.now()

        serverLabel = _(u'(Server: {0}-{1})').format(
            self.__serverLabel,
            self.__projectId) if self.__serverLabel else u''

        encoder = MultipartEncoder(
            fields={
                self.__uploadFieldName: (
                    # TEST-GUIDE (Apache-Commom-Fileupload) unterstützt im Moment nicht
                    # https://tools.ietf.org/html/rfc2231
                    # deswegen wird der Filename immer kodiert übertragen.
                    quote(self.__uploadFileName.encode('utf-8')),
                    io.open(self.__uploadFilePath, u'rb'),
                    self.__GetContentType(self.__uploadFileName))
            })

        callback = self._CreateMultipartEncoderMonitorCallback(encoder)
        monitor = MultipartEncoderMonitor(encoder, callback=callback)

        logPath = u'{reportDir}\\error.log'.format(
            reportDir=self.__reportApi.GetReportDir())
        logRawPath = u'{reportDir}\\error.raw.log'.format(
            reportDir=self.__reportApi.GetReportDir())
        logRawJsonPath = u'{reportDir}\\error.raw.json'.format(
            reportDir=self.__reportApi.GetReportDir())
        try:
            try:
                response = requests.post(
                    url=self.GetTargetUrl(),
                    data=monitor,
                    headers={
                        u'Accept':
                        u'application/{accept}'.format(accept=self.__accept),
                        u'Content-Type':
                        monitor.content_type
                    },
                    verify=False,
                    proxies=self.__proxies)
                response.raise_for_status()

                if self.__uploadAsync:
                    return self.__AsyncUpload(response, startUploadTime,
                                              serverLabel)

                return self.__SyncUpload(response, startUploadTime,
                                         serverLabel)

            except HTTPError as err:
                response = err.response

                # Raw Response sichern
                with io.open(logRawPath, u'w+', encoding=u'utf-8') as logFile:
                    logFile.write(u'{0}'.format(response.content))

                try:
                    logDict = response.json()
                except:
                    logDict = {}

                if isinstance(response.reason, bytes):
                    reason = response.reason.decode(u'utf-8', u'replace')
                else:
                    reason = response.reason

                raise UploadError(reason, response.status_code, logDict)

        except UploadError as err:

            # JSON Response sichern
            with io.open(logRawJsonPath, u'w+', encoding=u'utf-8') as logFile:
                logFile.write(u'{0}'.format(err.logEntries))

            # Error-Log Messages auswerten und aufbereiten für die Anzeige
            logMessages = u'\n'.join([
                u'Error {0}: {1}'.format(eachLogEntry.get(u'statusCode'),
                                         eachLogEntry.get(u'body'))
                for eachLogEntry in err.logEntries.get(u'messages', [])
            ])

            with io.open(logPath, u'w+', encoding=u'utf-8') as logFile:
                logFile.write(u'Error {code} - {reason}:\n{msg}\n'.format(
                    code=err.statusCode, reason=err.reason, msg=logMessages))

            endUploadTime = datetime.datetime.now()
            EPrint(
                _(u'Die ATX-Übertragung [{files}] war erfolgreich {serverLabel} '
                  u'(Generator v{version}), '
                  u'die Verarbeitung der Dateien führte jedoch zu Fehlern ({errCode}):\r\n'
                  u'{msg}'
                  u'Error-Log: {logPath}\r\n'
                  u'Uploaddauer: {duration}').format(
                      logPath=logPath,
                      msg=logMessages,
                      errCode=err.statusCode,
                      files=self.__uploadFilePath,
                      version=self.__version,
                      duration=str(endUploadTime - startUploadTime).split(
                          u'.', 1)[0],
                      serverLabel=serverLabel))
            return False

        except RequestException as err:
            EPrint(
                _(u'Die ATX-Übertragung [{files}] {serverLabel} konnte nicht statt '
                  u'finden:\r\n{reason}').format(reason=str(err),
                                                 files=self.__uploadFilePath,
                                                 serverLabel=serverLabel))
            return False
Exemplo n.º 8
0
def ProcessReport(reportApi, isPackageExecution):
    '''
    Führt die Reportgenerierung aus.
    @param reportApi: Aktuelles Objekt der ReportAPI.
    @type reportApi: ReportApi
    @param isPackageExecution: Handelt es sich um ein PackageReport.
    @type isPackageExecution: bool
    '''
    if not isinstance(isPackageExecution, bool):
        EPrint(u'isPackageExecution ist kein boolscher Wert!')
        return

    # Generierung startet
    DPrint(
        LEVEL_NORMAL,
        _(u"ATX-Dokument aus Report [{1}] mit Generator v{0} "
          u"wird erstellt...").format(GetVersion(), reportApi.GetDbFile()))
    startGenerateTime = datetime.datetime.now()

    try:
        url = Config.GetSetting(reportApi, u'serverURL')
        port = int(Config.GetSetting(reportApi, u'serverPort'))
        contextPath = Config.GetSetting(reportApi, u'serverContextPath')
        useHttps = Config.GetSetting(reportApi,
                                     u'useHttpsConnection') == u'True'
        proxies = CreateRequestProxySettings(reportApi)
        serverVersion = GetServerVersion(useHttps, url, port, contextPath,
                                         proxies)
        authKey = Config.GetSetting(reportApi, u'uploadAuthenticationKey')

        hasServerConnection = (serverVersion != u"0.0.0")
        hasSameVersion = parse_version(serverVersion) == parse_version(
            GetVersion())

        warnMsgNotUpToDateVer = _(
            u"Der verwendete ATX-Reportgenerator v{0} ist "
            u"ungleich der Version {1} welche vom Server gefordert "
            u"wird!\n"
            u"Die passende Version steht zum Download bereit unter:\n{2}\n"
            u"Nach dem Download den Ordner ATX im Workspace im eingestellten "
            u"Template-Verzeichnis '{3}' ablegen/ersetzen."
            u".").format(
                GetVersion(), serverVersion,
                GetDownloadLinkForATXMako(useHttps, url, port, contextPath,
                                          authKey),
                Api().GetSetting(u"templatePath"))

        # Warnung mit Downloadlink zur Server-Mako-Version anbieten.
        if hasServerConnection and not hasSameVersion:
            WPrint(warnMsgNotUpToDateVer)

        splitter = reportApi.GetDbDir().rfind(u'\\')
        zipFileName = reportApi.GetDbDir()[splitter + 1:]

        try:
            worker = ConvertReportToATX(reportApi, GetVersion(),
                                        isPackageExecution)
        except EmptyReportException:
            # Der Report hat keine verwertbaren Testcases erzeugt und daher wird die Generierung
            # abgebrochen
            WPrint(
                _(u'Der Report enthält keine Testfalldaten und wird daher verworfen.'
                  ))
            return

        # Wenn Target Verzeichnis nicht bereits angelegt, dann anlegen.
        targetDir = GetExtendedWindowsPath(reportApi.GetReportDir())
        if not os.path.exists(targetDir):
            os.makedirs(targetDir)

        atxFileName = u'report.xml'
        atxFilePath = os.path.join(targetDir, atxFileName)

        # ATX-Datei anlegen und befüllen.
        worker.CreateATXXmlFile(atxFilePath)

        ShowInfoOnTaskManager(reportApi,
                              _(u"Zip-Archiv für Upload wird erstellt..."))

        zipFileNameWithExtension = u'{0}.zip'.format(zipFileName)

        fileList = worker.GetFiles()

        # Zusätzliche Dateien aus dem Report Verzeichnis anziehen: eine Zip erstellen
        dbDir = reportApi.GetDbDir()
        reportDir = reportApi.GetReportDir()
        archiveMiscFiles = Config.GetSetting(reportApi,
                                             u'archiveMiscFiles').strip()
        archiveMiscPrefix = Config.GetSetting(
            reportApi, u'archiveMiscFilePrefix').strip()

        additionalFilesZipPath = ScanReportDir(
            reportApi,
            Api(),
            dbDir,
            archiveMiscFiles,
        ).CreateZipArchive(archiveMiscPrefix, reportDir)

        # Ref Pfade sammeln und jeden Testcase mit der Zip verknüpfen
        if additionalFilesZipPath:
            refs = []
            for item in fileList:
                if item[u'ref'] not in refs:
                    refs.append(item[u'ref'])
                    fileList.append({
                        u'file': additionalFilesZipPath,
                        u'ref': item[u'ref'],
                        u'comment': None,
                        u'refPathType': u"TEST-CASE",
                        u'removeFileAfterZipped': False
                    })

        # **** ZIP mit ATX Xml, Mapping Xml, TRF usw. erstellen
        zipArchive = ZipArchive(reportApi, zipFileNameWithExtension,
                                atxFilePath, fileList, worker.GetReviews())
        if not zipArchive.Make():
            # Fehler bei der Erstellung des Zip
            EPrint(_(u'Fehler beim Erstellen des Zip-Archivs.'))
        else:
            # Temp-Dateien ggf. löschen
            __CleanUpArchiveFiles(fileList)

        # Generierung erfolgt
        endGenerateTime = datetime.datetime.now()
        DPrint(
            LEVEL_NORMAL,
            _(u"ATX-Dokument aus Report [{1}] mit Generator v{0} "
              u"erzeugt (Dauer: {2}).").format(
                  GetVersion(), reportApi.GetDbFile(),
                  str(endGenerateTime - startGenerateTime).split('.')[0]))

        # Upload zum Server
        if Config.GetSetting(reportApi, u'uploadToServer') == u'True':

            ShowInfoOnTaskManager(reportApi, _(u"Daten werden hochgeladen..."))

            # Prüfe Option nur Projekte hochladen
            optionUploadOnlyPrjs = u'uploadOnlyProjectReport'
            if Config.GetSetting(
                    reportApi,
                    optionUploadOnlyPrjs) == u"True" and isPackageExecution:
                DPrint(
                    LEVEL_NORMAL, _(u"ATX Upload übersprungen"),
                    _(u"Option '{0}' ist aktiviert.").format(
                        optionUploadOnlyPrjs))
                return

            # Prüfe Verbindung
            if not hasServerConnection:
                EPrint(
                    _(u"ATX Upload abgebrochen! Keine Verbindung zum Server möglich, bitte "
                      u"Einstellungen überprüfen."))
                return

            # Versionsabgleich -> bei Fehler abbrechen
            if not hasSameVersion:
                EPrint(
                    _(u"ATX Upload abgebrochen! {0}").format(
                        warnMsgNotUpToDateVer))
                return

            uploader = UploadManager(reportApi,
                                     GetVersion(),
                                     u'file-upload',
                                     zipFileNameWithExtension,
                                     zipArchive.GetZipFilePath(),
                                     u'json',
                                     url,
                                     port,
                                     useHttps=useHttps,
                                     contextPath=contextPath)
            if uploader.StartUpload():
                # Wenn alles erfolgreich war und gewünscht, dann Dateien wieder löschen
                if Config.GetSetting(reportApi,
                                     u'cleanAfterSuccessUpload') == u'True':
                    ShowInfoOnTaskManager(
                        reportApi,
                        _(u"Aufräumarbeiten werden durchgeführt..."))
                    shutil.rmtree(targetDir, True)
    except SameNameError as ne:
        errorMessage = _(
            u'Der Name {0} wird sowohl für eine Datei und für einen Ordner auf der '
            u'selben Dateiebene verwendet. Dies ist für ATX-Darstellung nicht '
            u'zulässig.'
            u'Bitte benennen Sie den Ordner oder das Package um.').format(ne)
        with io.open(os.path.join(u'\\\\?\\' + reportApi.GetReportDir(),
                                  u'error.log'),
                     u'w',
                     encoding=u"utf-8") as fh:
            fh.write(errorMessage)
        EPrint(errorMessage)
    except BaseException as ex:
        import traceback
        EPrint(u'Exception in ReportPackage:\r\n{0}\r\n{1}'.format(
            ex, traceback.format_exc()))
Exemplo n.º 9
0
def __InitProcessReport(reportApi, isPackageExecution):
    '''
    Initialisiert die Reportgenerierung.
    @param reportApi: Aktuelles Objekt der ReportAPI.
    @type reportApi: ReportApi
    @param isPackageExecution: Handelt es sich um ein PackageReport.
    @type isPackageExecution: bool
    '''
    # Thread Lock setzen
    if not hasattr(Api(), "atxUpdateEvent"):
        Api().atxUpdateEvent = threading.BoundedSemaphore()

    try:
        atxReportTemplateDir = os.path.join(Api().GetSetting("templatePath"),
                                            "ATX")
        url = Config.GetSetting(reportApi, 'serverURL')
        port = Config.Cast2Int(Config.GetSetting(reportApi, 'serverPort'),
                               8085)
        contextPath = Config.GetSetting(reportApi, 'serverContextPath')
        isAutoUpdate = Config.GetSetting(reportApi,
                                         'autoATXGeneratorUpdate') == 'True'
        useHttps = Config.GetSetting(reportApi, 'useHttpsConnection') == 'True'
        proxies = CreateRequestProxySettings(reportApi)
        serverVersion = GetServerVersion(useHttps, url, port, contextPath,
                                         proxies)
        uploadToServer = Config.GetSetting(reportApi, 'uploadToServer')
        serverLabel = Config.GetSetting(reportApi, 'serverLabel')
        projectId = Config.GetSetting(reportApi, 'projectId')
        authKey = Config.GetSetting(reportApi, 'uploadAuthenticationKey')

        # Debugausgabe
        DPrint(
            LEVEL_VERBOSE,
            _(u"ATX-Generator für Report [{0}] wird mit folgenden "
              u"Eigenschaften gestartet:\n"
              u"serverLabel: {9}\n"
              u"projectId: {10}\n"
              u"serverURL: {1}\n"
              u"serverPort: {2}\n"
              u"serverContextPath: {3}\n"
              u"autoATXGeneratorUpdate: {4}\n"
              u"useHttpsConnection: {5}\n"
              u"serverVersion: {6}\n"
              u"reportGenVersion: {7}\n"
              u"uploadToServer: {8}\n"
              u"authKey: {11}\n").format(reportApi.GetDbFile(), url, port,
                                         contextPath,
                                         isAutoUpdate, useHttps, serverVersion,
                                         GetVersion(), uploadToServer,
                                         serverLabel, projectId,
                                         u"****" if authKey else u""))

        hasServerConnection = (serverVersion != u"0.0.0")
        hasSameVersion = parse_version(serverVersion) == parse_version(
            GetVersion())

        # AutoUpdate ab Version 1.5.0 verfügbar
        hasAutoUpdateVersion = parse_version(serverVersion) >= parse_version(
            u"1.5.0")

        # Wenn Verbindung besteht und Update notwendig und verlangt, dann durchführen.
        if hasServerConnection and hasAutoUpdateVersion and isAutoUpdate and not hasSameVersion:
            # Alle ATX-Reportgeneratoren an der Stelle fürs Auto-Update synchronisieren
            Api().atxUpdateEvent.acquire()

            SPrint(
                _(u"ATX AutoUpdate {1} wird gestartet für Update "
                  u"auf Generator v{0} ...").format(
                      serverVersion, (_(u"(Server: {0})").format(serverLabel)
                                      if serverLabel else u"")))

            # Update durchführen
            if __AutoUpdate(atxReportTemplateDir, proxies, useHttps, url, port,
                            contextPath, authKey):
                # Neuen Generator mit alter Config in dem Update-Thread anstarten
                from lib.report.handler.python.PythonHandler import PythonHandler
                handler = PythonHandler.CheckDir(PythonHandler,
                                                 atxReportTemplateDir)

                # Freigeben für nächsten Thread der im folgenden 'handler' aufgerufen wird
                Api().atxUpdateEvent.release()

                # Wenn es sich um eine Liste handelt, dann sind Fehlermeldungen hinterlegt.
                if isinstance(handler, list):
                    EPrint(u"ATX PythonHandler Errors: {0}".format(handler))
                else:
                    if reportApi.IsProjectReport():
                        handler.RenderProject(reportApi)
                    else:
                        handler.RenderPackage(reportApi)
            else:
                EPrint(_(u"ATX-Generierung mit Upload war nicht möglich!"))
                # Freigeben für nächsten Thread
                Api().atxUpdateEvent.release()
        else:
            # Report normal verarbeiten
            ProcessReport(reportApi, isPackageExecution)
    except BaseException as err:
        EPrint(u"InitProcessReport failed: {0}".format(err))
Exemplo n.º 10
0
def __DownloadAndUnZipATXMakoInTemplateDir(targetZipDir, proxies, useHttps,
                                           hostUrl, port, contextUrl, authKey):
    '''
    Downloaded das passende Mako vom Server und entpackt die Version im Workspace
    Templateverzeichnis und entfernt wieder die Zip.
    @param targetZipDir: Verzeichnis in welches das Zip entpackt werden soll.
    @type targetZipDir: str
    @param proxies: Dict mit dem Mapping der Protokolle bei Verwendung eines Proxies
    @type proxies: dict
    @param useHttps: True, wenn eine Https-Verbindung verwendet werden soll, sonst False.
    @type useHttps: boolean
    @param hostUrl: Haupt-URL
    @type hostUrl: str
    @param port: Port
    @type port: integer
    @param contextUrl: Context-URL (kann u.U. auch leer sein)
    @type contextUrl: str
    @param authKey: Authentifizierungsschlüssel für den Download
    @type authKey: str
    @return: True, wenn Download erfolgreich, sonst False.
    @rtype: boolean
    '''
    try:
        # Download der aktuellen Mako in maximal 90s .
        response = requests.get(GetDownloadLinkForATXMako(
            useHttps, hostUrl, port, contextUrl, authKey),
                                timeout=90,
                                verify=False,
                                proxies=proxies)

        # Download
        downloadTarget = os.path.join(Api().GetSetting(u"templatePath"),
                                      u"ATX.zip")
        with open(downloadTarget, u'wb') as output:
            output.write(response.content)

        # Bestands-Generator feststellen
        if os.path.isdir(targetZipDir):

            # Wenn Verzeichnis bereits vorhanden, dann Python-Inhalte löschen,
            # damit Templates nicht zugemüllt wird
            files = glob.glob(os.path.join(targetZipDir, "*.py*"))
            try:
                for each in files:
                    os.remove(each)

                # Python 3 File-Cache löschen
                pyCacheDir = os.path.join(targetZipDir, "__pycache__")
                if os.path.exists(pyCacheDir):
                    shutil.rmtree(pyCacheDir, ignore_errors=False)

            except BaseException as err:
                WPrint(u"ATX folder file could not removed: {0}".format(err))
                # Fallback, falls das einzelne Löschen nicht möglich ist.
                if os.path.exists(targetZipDir):
                    shutil.rmtree(targetZipDir, ignore_errors=False)

        # Unzip
        with zipfile.ZipFile(downloadTarget) as zf:
            zf.extractall(targetZipDir)

        # Remove Zip-File
        os.remove(downloadTarget)

        return True
    except BaseException as err:
        EPrint(u"ATX Zip Update failed: {0}".format(err))
        return False