def run(self):
        appdef = None
        projFile = QgsProject.instance().fileName()
        if projFile:
            appdefFile = projFile + ".appdef"
            if os.path.exists(appdefFile):
                if pluginSetting("askreload") == "Ask":
                    ret = QMessageBox.question(
                        self.iface.mainWindow(), "Web app builder",
                        "This project has been already published as a web app.\n"
                        "Do you want to reload app configuration?",
                        QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
                    if ret == QMessageBox.Yes:
                        appdef = loadAppdef(appdefFile)
                elif pluginSetting("askreload") == "Open last configuration":
                    appdef = loadAppdef(appdefFile)
        initialize()
        # reset credential token in case related credentials are changed
        utils.resetCachedToken()
        try:
            dlg = MainDialog(appdef)
            dlg.exec_()
        except:
            dlg.progressBar.setMaximum(100)
            dlg.progressBar.setValue(0)
            dlg.progressBar.setVisible(False)
            dlg.progressLabel.setVisible(False)
            QApplication.restoreOverrideCursor()

            QgsMessageLog.logMessage(traceback.format_exc(),
                                     "WebAppBuilder",
                                     level=QgsMessageLog.CRITICAL)
            QMessageBox.critical(
                self.iface.mainWindow(),
                "Unmanaged error. See QGIS log for more details.")
def appSDKification(folder, progress):
    ''' zip app folder and send to WAB compiler to apply SDK compilation.
    The returned zip will be the official webapp
    '''
    progress.oscillate()

    progress.setText("Get Authorization token")
    try:
        global __appSDKification_doAgain
        if __appSDKification_doAgain:
            QgsMessageLog.logMessage("Renew token in case of it is expired and retry", level=QgsMessageLog.WARNING)
            utils.resetCachedToken()
        token = utils.getToken()
    except Exception as e:
        pub.sendMessage(utils.topics.endAppSDKification, success=False, reason=str(e))
        return

    # zip folder to send for compiling
    progress.setText("Preparing data to compile")
    zipFileName = tempFilenameInTempFolder("webapp.zip", "webappbuilder")
    try:
        with zipfile.ZipFile(zipFileName, "w") as zf:
            relativeFrom = os.path.dirname(folder)
            for dirname, subdirs, files in os.walk(folder):
                # exclude data folder
                if 'data' in subdirs:
                    subdirs.remove('data')
                if relativeFrom in dirname:
                    zf.write(dirname, dirname[len(relativeFrom):])
                for filename in files:
                    fiename = os.path.join(dirname, filename)
                    zf.write(fiename, fiename[len(relativeFrom):])
    except:
        msg = "Could not zip webapp folder: {}".format(folder)
        pub.sendMessage(utils.topics.endAppSDKification, success=False, reason=msg)
        return

    # prepare data for WAB compiling request
    with open(zipFileName, 'rb') as f:
        fileContent = f.read()
    fields = { 'file': (os.path.basename(zipFileName), fileContent) }
    payload, content_type = encode_multipart_formdata(fields)

    headers = {}
    headers["authorization"] = "Bearer {}".format(token)
    headers["Content-Type"] = content_type

    # prepare request (as in NetworkAccessManager) but without blocking request
    # do http post
    progress.setText("Wait compilation")

    global __anam
    if __anam:
        del __anam
        __anam = None
    __anam = NetworkAccessManager(debug=pluginSetting("logresponse"))
    __anam.request(utils.wabCompilerUrl(), method='POST', body=payload, headers=headers, blocking=False)
    __anam.reply.finished.connect( lambda: manageFinished(__anam, zipFileName, folder, progress) )
def checkSDKServerVersion():
    localVersion = utils.sdkVersion()

    token = utils.getToken()

    headers = {}
    headers["authorization"] = "Bearer {}".format(token)

    nam = NetworkAccessManager(debug=pluginSetting("logresponse"))
    try:
        resp, text = nam.request(wabVersionUrl(), headers=headers)
    except Exception as e:
        # check if 401/403 => probably token expired
        permissionDenied = utils.isPermissionDenied(str(e))
        if not permissionDenied:
            raise e
        else:
            # renew token and try again
            utils.resetCachedToken()
            token = utils.getToken()

            # retry call
            headers["authorization"] = "Bearer {}".format(token)
            try:
                resp, text = nam.request(wabVersionUrl(), headers=headers)
            except Exception as e:
                # check if 401/403 => probably token expired
                permissionDenied = utils.isPermissionDenied(str(e))
                if not permissionDenied:
                    raise e
                else:
                    raise Exception(
                        "Permission denied with current Connect credentials")

    remoteVersion = json.loads(text)["boundless-sdk"]
    if localVersion != remoteVersion:
        raise VersionMismatchError(
            "The server SDK version (%s) is different from the expected version (%s)"
            % (remoteVersion, localVersion))