def fApplicationDebugOutputCallbackHandler(oBugId, oProcess, bIsMainProcess, asbMessages): if dxConfig["bQuiet"]: return uLineNumber = 0 sDebug = "debug" oConsole.fLock() for sbMessage in asbMessages: uLineNumber += 1 if uLineNumber == 1: # we will create a box shape to show which messages belong together. # On the first line we will branch down and right if the message is multi-line. sPrefix = " " if len(asbMessages) == 1 else "" else: # if more lines folow, show a vertical stripe, otherwise bend right on the last line sPrefix = "" if uLineNumber == len(asbMessages) else "" fOutputMessageForProcess( COLOR_OUTPUT, CHAR_OUTPUT if uLineNumber == 1 else None, oProcess, bIsMainProcess, COLOR_INFO, "debug", COLOR_NORMAL, sPrefix, COLOR_HILITE, str(sbMessage, 'latin1'), ) sDebug = " " oConsole.fUnlock()
def fOutputLogo(): # We will use the above ASCII and color data to create a list of arguments # that can be passed to oConsole.fOutput in order to output the logo in color: oConsole.fLock() try: for uLineIndex in range(len(asBugIdLogo)): uCurrentColor = COLOR_NORMAL bUnderlined = False asBugIdLogoPrintArguments = [""] sCharsLine = asBugIdLogo[uLineIndex] sColorsLine = asBugIdLogoColors[uLineIndex] uColorIndex = 0 for uColumnIndex in range(len(sCharsLine)): sColor = sColorsLine[uColorIndex] uColorIndex += 1 if sColor == "_": bUnderlined = not bUnderlined sColor = sColorsLine[uColorIndex] uColorIndex += 1 uColor = (sColor != " " and (0x0F00 + int(sColor, 16)) or COLOR_NORMAL) + ( bUnderlined and CONSOLE_UNDERLINE or 0) if uColor != uCurrentColor: asBugIdLogoPrintArguments.extend([uColor, ""]) uCurrentColor = uColor sChar = sCharsLine[uColumnIndex] asBugIdLogoPrintArguments[-1] += sChar oConsole.fOutput(*asBugIdLogoPrintArguments) finally: oConsole.fUnlock()
def fVerboseOutputHelper(b0Selected, sItemPath, sRegExpType, rRegExp, o0Match): oConsole.fLock() try: oConsole.fOutput( " ", [COLOR_SELECT_MAYBE, CHAR_SELECT_MAYBE] if b0Selected is None else [COLOR_SELECT_YES, CHAR_SELECT_YES] if b0Selected else [COLOR_SELECT_NO, CHAR_SELECT_NO], COLOR_NORMAL, " ", sItemPath, COLOR_DIM, " (", "matches" if o0Match else "does not match", " ", sRegExpType, " reg.exp. ", str(rRegExp.pattern), ")", ) if o0Match and len(o0Match.groups()): asSubMatchesOutput = [] for sSubMatch in oMatch.groups(): asSubMatchesOutput += [ ", " if len(asSubMatchesOutput) else "", COLOR_NORMAL, sSubMatch, COLOR_DIM ] oConsole.fOutput(COLOR_DIM, " Sub-matches: ", asSubMatchesOutput, ".") finally: oConsole.fUnlock()
def fOutputExceptionInformation(oException, oTraceback): if m0DebugOutput: m0DebugOutput.fConsoleOutputExceptionDetails(oException, o0Traceback = oTraceback); oConsole.fLock(); else: oConsole.fLock(); try: oConsole.fOutput("An internal exception has happened but the 'mDebugOutput' module is not"); oConsole.fOutput("available to show advanced details. Please download this module to get"); oConsole.fOutput("more detailed information about this issue."); oConsole.fOutput(); oConsole.fOutput("Here's the exception:"); oConsole.fOutput(" ", COLOR_INFO, oException.__class__.__name__, COLOR_NORMAL, "("); try: for xArg in oException.args: oConsole.fOutput(" ", COLOR_INFO, repr(xArg), COLOR_NORMAL, ","); except: oConsole.fOutput(" ", COLOR_INFO, repr(oException)); oConsole.fOutput(" ", COLOR_NORMAL, ")"); except: oConsole.fUnlock(); raise; try: oConsole.fOutput(); oConsole.fOutput("Please report the above details at the below web-page so it can be addressed:"); oConsole.fOutput(" ", COLOR_INFO, "https://github.com/SkyLined/BugId/issues/new"); oConsole.fOutput("If you do not have a github account, or you want to report this issue"); oConsole.fOutput("privately, you can also send an email to:"); oConsole.fOutput(" ", COLOR_INFO, "*****@*****.**"); oConsole.fOutput(); oConsole.fOutput("In your report, please ", COLOR_HILITE, "copy ALL the information about the exception reported"); oConsole.fOutput(COLOR_HILITE, "above, as well as the stack trace and BugId version information", COLOR_NORMAL, ". This makes"); oConsole.fOutput("it easier to determine the cause of this issue and makes for faster fixes."); oConsole.fOutput(); if not any([sVerbose in sys.argv[1:] for sVerbose in ["-v", "/v", "-V", "/V", "--verbose=true"]]): oConsole.fOutput("If you can reproduce the issue, it would help a lot if you can run BugId in"); oConsole.fOutput("verbose mode by adding the ", COLOR_INFO, "--verbose", COLOR_NORMAL, " command-line argument."); oConsole.fOutput("as in: ", COLOR_HILITE, "BugId -v ", " ".join(sys.argv[1:])); oConsole.fOutput(); fOutputVersionInformation( bCheckForUpdates = False, bShowInstallationFolders = False, dsAdditionalVersion_by_sName = fdsGetAdditionalVersionByName(), ); oConsole.fOutput("Thank you in advance for helping to improve BugId!"); finally: oConsole.fUnlock();
def fOutputApplicationKeyWordHelp(sApplicationKeyword, dxApplicationSettings): oConsole.fLock(); try: oConsole.fOutput("Known application settings for ", COLOR_INFO, sApplicationKeyword); if "sBinaryPath" in dxApplicationSettings: sBinaryPath = dxApplicationSettings["sBinaryPath"]; if sBinaryPath is None: oConsole.fOutput( COLOR_WARNING, CHAR_WARNING, COLOR_NORMAL, " The application cannot be found on your system.", ); else: oConsole.fOutput(" Binary path: ", COLOR_INFO, sBinaryPath); elif "dxUWPApplication" in dxApplicationSettings: dxUWPApplication = dxApplicationSettings["dxUWPApplication"]; oConsole.fOutput(" UWP Application information:"); oConsole.fOutput(" Package name: ", COLOR_INFO, dxUWPApplication["sPackageName"]); oConsole.fOutput(" Id: ", COLOR_INFO, dxUWPApplication["sId"]); if "asApplicationAttachToProcessesForExecutableNames" in dxApplicationSettings: asApplicationAttachToProcessesForExecutableNames = dxApplicationSettings["asApplicationAttachToProcessesForExecutableNames"]; oConsole.fOutput(" Attach to additional processes running any of the following binaries:"); for sBinaryName in asApplicationAttachToProcessesForExecutableNames: oConsole.fOutput(" ", COLOR_INFO, sBinaryName); if "fasGetStaticArguments" in dxApplicationSettings: fasGetApplicationStaticArguments = dxApplicationSettings["fasGetStaticArguments"]; asApplicationStaticArguments = fasGetApplicationStaticArguments(bForHelp = True); oConsole.fOutput(" Default static arguments:"); oConsole.fOutput(" ", COLOR_INFO, " ".join(asApplicationStaticArguments)); if "fasGetOptionalArguments" in dxApplicationSettings: fasGetOptionalArguments = dxApplicationSettings["fasGetOptionalArguments"]; asApplicationOptionalArguments = fasGetOptionalArguments(bForHelp = True); oConsole.fOutput(" Default optional arguments:"); oConsole.fOutput(" ", COLOR_INFO, " ".join(asApplicationOptionalArguments)); if "dxConfigSettings" in dxApplicationSettings: dxApplicationConfigSettings = dxApplicationSettings["dxConfigSettings"]; if dxApplicationConfigSettings: oConsole.fOutput(" Application specific settings:"); for sSettingName, xValue in dxApplicationConfigSettings.items(): oConsole.fOutput(" ", COLOR_INFO, sSettingName, COLOR_NORMAL, ": ", COLOR_INFO, json.dumps(xValue)); finally: oConsole.fUnlock();
def fOutputUsageInformation(): oConsole.fLock() try: fOutputLogo() oConsole.fOutput(COLOR_HILITE, "Usage:") oConsole.fOutput( COLOR_INFO, " zyp.py [options] <source file or folder> <destination .zip file>" ) oConsole.fOutput( COLOR_INFO, " unzyp.py [options] <source .zip file> [<destination folder>]") oConsole.fOutput() oConsole.fOutput( COLOR_INFO, " zyp.py", COLOR_NORMAL, " will add the source files or all files in the source folder to the" ) oConsole.fOutput( " destination .zip file. The destination .zip file is created if it does not" ) oConsole.fOutput( " exist but files are added to any existing destination .zip file. If a file" ) oConsole.fOutput( " already exists in the destination .zip file, it is overwritten." ) oConsole.fOutput() oConsole.fOutput( COLOR_INFO, " unzyp.py", COLOR_NORMAL, " will extract all files in the source .zip file to the destination" ) oConsole.fOutput( " folder. The destination folder is created if it does not exist and files" ) oConsole.fOutput( " are added to any existing destination folder. If a file already exists in" ) oConsole.fOutput(" the destination folder, it is overwritten.") oConsole.fOutput() oConsole.fOutput(COLOR_INFO, "Options:") oConsole.fOutput(" ", COLOR_INFO, "-h", COLOR_NORMAL, ", ", COLOR_INFO, "--help") oConsole.fOutput(" This cruft.") oConsole.fOutput(" ", COLOR_INFO, "--version") oConsole.fOutput(" Show version information.") oConsole.fOutput(" ", COLOR_INFO, "--version-check") oConsole.fOutput(" Check for updates and show version information.") oConsole.fOutput(" ", COLOR_INFO, "--license") oConsole.fOutput(" Show license information.") oConsole.fOutput(" ", COLOR_INFO, "--license-update") oConsole.fOutput( " Download license updates and show license information.") oConsole.fOutput(" ", COLOR_INFO, "--arguments", COLOR_NORMAL, "=<", COLOR_INFO, "file path", COLOR_NORMAL, ">") oConsole.fOutput( " Load additional arguments from the provided value and insert them in place" ) oConsole.fOutput(" of this argument.") oConsole.fOutput(COLOR_INFO, " -d", COLOR_NORMAL, ", ", COLOR_INFO, "--debug", COLOR_NORMAL) oConsole.fOutput( " Output debug information while zipping/unzipping files.") oConsole.fOutput(COLOR_INFO, " -l", COLOR_NORMAL, ", ", COLOR_INFO, "--list", COLOR_NORMAL) oConsole.fOutput( " (unzyp only) List all files in a zip file without extracting them." ) oConsole.fOutput() oConsole.fOutput(COLOR_HILITE, "Exit codes:") oConsole.fOutput( " ", 0x0F0A, "0", COLOR_NORMAL, " = zyp/unzyp did not compress/decompress any files.") oConsole.fOutput( " ", 0x0F0A, "1", COLOR_NORMAL, " = zyp/unzyp compressed/decompressed files successfully.") oConsole.fOutput( " ", 0x0F0C, "2", COLOR_NORMAL, " = zyp/unzyp was unable to parse the command-line arguments provided." ) oConsole.fOutput( " ", 0x0F0C, "3", COLOR_NORMAL, " = zyp/unzyp ran into an internal error: please report the details!" ) oConsole.fOutput(" ", 0x0F0C, "4", COLOR_NORMAL, " = zyp/unzyp cannot read from the given source.") oConsole.fOutput( " ", 0x0F0C, "5", COLOR_NORMAL, " = zyp/unzyp cannot write to the given destination.") finally: oConsole.fUnlock()
def fOutputUsageInformation(): oConsole.fLock() try: fOutputLogo() axBoolean = [ "[=", COLOR_INFO, "true", COLOR_NORMAL, "|", COLOR_INFO, "false", COLOR_NORMAL, "]" ] oConsole.fOutput(COLOR_HILITE, "Usage:") oConsole.fOutput() oConsole.fOutput( COLOR_INFO, " rs.py [options] [<path> [<path> [...]]] [-- <command>]") oConsole.fOutput() oConsole.fOutput(COLOR_HILITE, "Options:") oConsole.fOutput(" ", COLOR_INFO, "-h", COLOR_NORMAL, ", ", COLOR_INFO, "--help") oConsole.fOutput(" This cruft.") oConsole.fOutput(" ", COLOR_INFO, "--version") oConsole.fOutput(" Show version information.") oConsole.fOutput(" ", COLOR_INFO, "--version-check") oConsole.fOutput(" Check for updates and show version information.") oConsole.fOutput(" ", COLOR_INFO, "--license") oConsole.fOutput(" Show license information.") oConsole.fOutput(" ", COLOR_INFO, "--license-update") oConsole.fOutput( " Download license updates and show license information.") oConsole.fOutput(" ", COLOR_INFO, "--arguments", COLOR_NORMAL, "=<", COLOR_INFO, "file path", COLOR_NORMAL, ">") oConsole.fOutput( " Load additional arguments from the provided value and insert them in place" ) oConsole.fOutput(" of this argument.") oConsole.fOutput(" ", COLOR_INFO, "-q", COLOR_NORMAL, ", ", COLOR_INFO, "--quiet", axBoolean) oConsole.fOutput(" Output only essential information.") oConsole.fOutput(" ", COLOR_INFO, "-v", COLOR_NORMAL, ", ", COLOR_INFO, "--verbose", axBoolean) oConsole.fOutput(" Verbose output.") oConsole.fOutput(" ", COLOR_INFO, "-p", COLOR_NORMAL, ", ", COLOR_INFO, "--pause", axBoolean) oConsole.fOutput( " Wait for user to press ENTER before terminating.") oConsole.fOutput(" ", COLOR_INFO, "-u", COLOR_NORMAL, ", ", COLOR_INFO, "--unicode", axBoolean) oConsole.fOutput( " Remove all '\0' chars from the file before scanning to improvise scanning" ) oConsole.fOutput(" utf-16 encoded ASCII characters.") oConsole.fOutput(" ", COLOR_INFO, "-e", COLOR_NORMAL, ", ", COLOR_INFO, "--uedit", axBoolean) oConsole.fOutput( " Start UltraEdit 64-bit for each matched file and scroll to the first matched line (if any)." ) oConsole.fOutput(" ", COLOR_INFO, "-l", COLOR_NORMAL, ", ", COLOR_INFO, "--lines <lines>") oConsole.fOutput( " Show the provided number of lines of the file's content around each match." ) oConsole.fOutput(" ", COLOR_INFO, "<lines>", COLOR_NORMAL, " can take two formats: ", COLOR_INFO, "[-/+]N", COLOR_NORMAL, " and ", COLOR_INFO, "-N+N", COLOR_NORMAL, ".") oConsole.fOutput( " Where N is a integer number, positive/negative numbers determine the number" ) oConsole.fOutput( " of lines to show after/before the match respectively.") oConsole.fOutput(" ", COLOR_INFO, "<path>", COLOR_NORMAL, " [", COLOR_INFO, "<path>", COLOR_NORMAL, " [", COLOR_INFO, "...", COLOR_NORMAL, "]]") oConsole.fOutput( " Apply matching only to the provided files/folders. If not path is" ) oConsole.fOutput( " provided, the current working directory is used.") oConsole.fOutput(" ", COLOR_INFO, "-r", COLOR_NORMAL, ", ", COLOR_INFO, "--recursive") oConsole.fOutput( " Apply matching to all files in all subfolders of the selected folders." ) oConsole.fOutput(" ", COLOR_INFO, "<regular expression> [<regular expression> [...]]") oConsole.fOutput( " Match the content or full path and name of files against the given regular" ) oConsole.fOutput( " expression(s). You must provide at least one regular expression." ) oConsole.fOutput(COLOR_HILITE, "Regular expression syntax:") oConsole.fOutput(" [", COLOR_INFO, "c", COLOR_NORMAL, "|", COLOR_INFO, "p", COLOR_NORMAL, "]", "[", COLOR_INFO, "!", COLOR_NORMAL, "]", "/", COLOR_INFO, "pattern", COLOR_NORMAL, "/", "[", COLOR_INFO, "flags", COLOR_NORMAL, "]") oConsole.fOutput() oConsole.fOutput(" [", COLOR_INFO, "c", COLOR_NORMAL, "|", COLOR_INFO, "p", COLOR_NORMAL, "]") oConsole.fOutput( " ", COLOR_INFO, "c", COLOR_NORMAL, " indicates the regular expression should be matched against the file's content" ) oConsole.fOutput( " (default). ", COLOR_INFO, "p", COLOR_NORMAL, " indicates the regular expression should be matched against the") oConsole.fOutput(" file's full path and name.") oConsole.fOutput(" [", COLOR_INFO, "!", COLOR_NORMAL, "]") oConsole.fOutput( " If ", COLOR_INFO, "!", COLOR_NORMAL, "is present, the match is inverted: files that match this regular expression" ) oConsole.fOutput(" are ", CONSOLE_UNDERLINE, "excluded", COLOR_NORMAL, " from the result instead of included. File that ", CONSOLE_UNDERLINE, "do not", COLOR_NORMAL, " match") oConsole.fOutput(" this regular expression are included.") oConsole.fOutput(" ", COLOR_INFO, "pattern") oConsole.fOutput( " A regular expression pattern following Python syntax.") oConsole.fOutput(" ", COLOR_INFO, "flags") oConsole.fOutput( " Any one of the single-letter regular expression flags available in Python." ) oConsole.fOutput() oConsole.fOutput( " For details on the syntax of Python regular expression patterns and flags" ) oConsole.fOutput(" please visit: ", COLOR_INFO, "https://docs.python.org/3/library/re.html", COLOR_NORMAL, ".") oConsole.fOutput(" ", COLOR_INFO, "--", COLOR_NORMAL, " <", COLOR_INFO, "command", COLOR_NORMAL, "> [", COLOR_INFO, "arguments", COLOR_NORMAL, "]") oConsole.fOutput( " Execute the specified command for all files that matched the given" ) oConsole.fOutput( " regular expressions. The command nad arguments can contain the following" ) oConsole.fOutput( " keys that will be replaced by the appropriate values:") oConsole.fOutput(" ", COLOR_INFO, "{d}", COLOR_NORMAL, " - the drive on which the file was found.") oConsole.fOutput(" ", COLOR_INFO, "{p}", COLOR_NORMAL, " - the folder path in which the file was found.") oConsole.fOutput(" ", COLOR_INFO, "{n}", COLOR_NORMAL, " - the name of the file (excluding the extension).") oConsole.fOutput(" ", COLOR_INFO, "{x}", COLOR_NORMAL, " - the extension of the file (including the dot).") oConsole.fOutput(" ", COLOR_INFO, "{f}", COLOR_NORMAL, " - the full path of the file (== ", COLOR_INFO, "{dpnx}", COLOR_NORMAL, ").") oConsole.fOutput(" Note: The above arguments can be combined: ", COLOR_INFO, "{dp}", COLOR_NORMAL, " will be replaced with the") oConsole.fOutput(" file's drive and path, and ", COLOR_INFO, "{nx}", COLOR_NORMAL, " will be replaced by the file's name and") oConsole.fOutput( " extension. The values for these keys will be surrounded by quotes unless" ) oConsole.fOutput(" preceed them with ", COLOR_INFO, "~", COLOR_NORMAL, " (e.g. ", COLOR_INFO, "\"{~n}{~x}\"", COLOR_NORMAL, " == ", COLOR_INFO, "{nx}", COLOR_NORMAL, ").") oConsole.fOutput( " ", COLOR_INFO, "{l}", COLOR_NORMAL, " - the line number on which the first match was found.") oConsole.fOutput( " Note: Repeating {l} gives you the next line number on which a match was" ) oConsole.fOutput( " found, or -1 if there are no more matches: {l},{l},{l} will be replaced with" ) oConsole.fOutput( " the line numbers of the first three matches, separated by commas." ) oConsole.fOutput(" ", COLOR_INFO, "{1}", COLOR_NORMAL, ", ", COLOR_INFO, "{2}", COLOR_NORMAL, ", ", COLOR_INFO, "{3}", COLOR_NORMAL, "... - the ", CONSOLE_UNDERLINE, "first path", COLOR_NORMAL, " match's sub-matches.") oConsole.fOutput( " Note: You can use numbers to insert groups from the last match against the" ) oConsole.fOutput( " file name or path. This may be useful to mass-rename files. If both a name" ) oConsole.fOutput( " and a path match exists, the name match is used. You can use the prefixes" ) oConsole.fOutput( " \"n\" and \"p\" to force using the name or path match, as in {n1} or {p2}." ) oConsole.fOutput(" For instance ", COLOR_INFO, "rs \"n/(.*)\\.old$/\" -- ren {f} {1}", COLOR_NORMAL, " will remove the \".old\" extension") oConsole.fOutput(" from all files in the current folder.") oConsole.fOutput() oConsole.fOutput(COLOR_HILITE, "Examples:") oConsole.fOutput(" ", COLOR_INFO, "rs /C+/ -p /P+/ -r") oConsole.fOutput( " Match all files in the current directory and all its sub-folders which path" ) oConsole.fOutput( " and name contains a sequence of 1 or more 'P'-s. Match the content of " ) oConsole.fOutput( " these files for a sequence of 1 or more 'C'-s. Output the path and name of" ) oConsole.fOutput( " the files that matched and the line number(s) on which the 'C'-s were found." ) oConsole.fOutput() oConsole.fOutput(" ", COLOR_INFO, "rs -p /P+/i C:\\ -r") oConsole.fOutput( " Match all files in the root of the C: drive and all its sub-folders which" ) oConsole.fOutput( " path and name contains a sequence of 1 or more 'p'-s (either upper- or" ) oConsole.fOutput( " lowercase). Output the path and name of the files that matched." ) oConsole.fOutput() oConsole.fOutput( " ", COLOR_INFO, "rs /class\\s+\\w+/m -p /\\.c(pp|xx)$/i -- notepad {f}") oConsole.fOutput( " Match all files in the current folder that have a .cpp or .cxx extension." ) oConsole.fOutput( " Match the content of these files against a C++ class definitions. Output" ) oConsole.fOutput( " the path, name and line numbers of the files and open each one in Notepad." ) oConsole.fOutput() oConsole.fOutput( " ", COLOR_INFO, "rs /struct\s+some_struct\s*{/m -r -p /\\.[ch](pp|xx)?$/i -l -1+16" ) oConsole.fOutput( " Match all files in the current folder that have a C/C++ extension." ) oConsole.fOutput( " Match the content of these files against the struct some_struct" ) oConsole.fOutput( " definitions. Output the path and name of the matched file(s) and the line" ) oConsole.fOutput(" before and up to 16 lines after each match.") oConsole.fOutput() oConsole.fOutput(COLOR_HILITE, "Exit codes:") oConsole.fOutput(" ", COLOR_INFO, "0", COLOR_NORMAL, " = rs did not match any files.") oConsole.fOutput(" ", COLOR_INFO, "1", COLOR_NORMAL, " = rs matched one or more files.") oConsole.fOutput( " ", COLOR_ERROR, "2", COLOR_NORMAL, " = rs was unable to parse the command-line arguments provided.") oConsole.fOutput( " ", COLOR_ERROR, "3", COLOR_NORMAL, " = rs ran into an internal error: please report the details!") finally: oConsole.fUnlock()
def fOutputVersionInformation(bCheckForUpdates, bShowInstallationFolders, dsAdditionalVersion_by_sName={}): # Read product details for rs and all modules it uses. aoProductDetails = mProductDetails.faoGetProductDetailsForAllLoadedModules( ) o0MainProductDetails = mProductDetails.fo0GetProductDetailsForMainModule() oConsole.fLock() try: aoProductDetailsCheckedForUpdates = [] aoProductDetailsSuccessfullyCheckedForUpdates = [] if bCheckForUpdates: for oProductDetails in aoProductDetails: if oProductDetails.o0Repository is None: continue aoProductDetailsCheckedForUpdates.append(oProductDetails) oConsole.fProgressBar( len(aoProductDetailsCheckedForUpdates) * 1.0 / len(aoProductDetails), "Checking %s for updates..." % oProductDetails.sProductName, ) try: oProductDetails.foGetLatestProductDetailsFromRepository() except mProductDetails.mExceptions.cProductDetailsException as oException: oConsole.fOutput( COLOR_ERROR, CHAR_ERROR, COLOR_NORMAL, " Version check for ", COLOR_INFO, oProductDetails.sProductName, COLOR_NORMAL, " failed: ", COLOR_INFO, str(oException), ) else: aoProductDetailsSuccessfullyCheckedForUpdates.append( oProductDetails) if len(aoProductDetailsSuccessfullyCheckedForUpdates) == 0: oConsole.fOutput( COLOR_WARNING, CHAR_WARNING, COLOR_NORMAL, "Failed to get any product version information.", ) oConsole.fOutput( " (This often indicates you are running a ", COLOR_INFO, "pre-release", COLOR_NORMAL, " version, or a version that is very ", COLOR_INFO, "out of date", COLOR_NORMAL, ").", ) oConsole.fOutput( " To try and resolve this issue, please update this product to the latest", ) oConsole.fOutput(" version and try again.", ) if f0OutputLogo: f0OutputLogo() oConsole.fOutput( "┌───[", COLOR_HILITE, " Version information ", COLOR_NORMAL, "]", sPadding="─", ) # Output the main product information first, then its dependencies alphabetically: if o0MainProductDetails: fOutputProductDetails( o0MainProductDetails, bIsMainProduct=True, bShowInstallationFolders=bShowInstallationFolders, bCheckForUpdates=bCheckForUpdates, bCheckForUpdatesSuccessful=o0MainProductDetails in aoProductDetailsSuccessfullyCheckedForUpdates, ) doRemainingProductDetails_by_sName = dict([ (oProductDetails.sProductName, oProductDetails) for oProductDetails in aoProductDetails if oProductDetails != o0MainProductDetails ]) for sProductName in sorted(doRemainingProductDetails_by_sName.keys()): oProductDetails = doRemainingProductDetails_by_sName[sProductName] fOutputProductDetails( oProductDetails, bIsMainProduct=False, bShowInstallationFolders=bShowInstallationFolders, bCheckForUpdates=bCheckForUpdates, bCheckForUpdatesSuccessful=oProductDetails in aoProductDetailsSuccessfullyCheckedForUpdates, ) asProductNames = (([o0MainProductDetails.sProductName] if o0MainProductDetails else []) + list(doRemainingProductDetails_by_sName.keys())) oConsole.fOutput( "│ ", CHAR_LIST, " ", COLOR_INFO, "Windows", COLOR_NORMAL, " version: ", COLOR_INFO, oSystemInfo.sOSName, COLOR_NORMAL, " release ", COLOR_INFO, oSystemInfo.sOSReleaseId, COLOR_NORMAL, ", build ", COLOR_INFO, oSystemInfo.sOSBuild, COLOR_NORMAL, " ", COLOR_INFO, oSystemInfo.sOSISA, COLOR_NORMAL, ".", ) oConsole.fOutput( "│ ", CHAR_LIST, " ", COLOR_INFO, "Python", COLOR_NORMAL, " version: ", COLOR_INFO, str(platform.python_version()), COLOR_NORMAL, " ", COLOR_INFO, fsGetPythonISA(), COLOR_NORMAL, ".", ) for (sName, sVersion) in dsAdditionalVersion_by_sName.items(): oConsole.fOutput( "│ ", CHAR_LIST, " ", COLOR_INFO, sName, COLOR_NORMAL, " version: ", COLOR_INFO, sVersion, COLOR_NORMAL, ".", ) oConsole.fOutput( "└", sPadding="─", ) finally: oConsole.fUnlock()
def fCheckPythonVersion(sApplicationName, asTestedPythonVersions, sBugURL): sPythonVersion = platform.python_version() uMajorVersion, uMinorVersion, uMicroVersion = [ int(s) for s in sPythonVersion.split(".") ] auTestedMajorVersions = set() bRunningInTestedMajorVersion = False bRunningInTestedVersion = False bRunningInOlderVersion = False for sTestedPythonVersion in asTestedPythonVersions: uTestedMajorVersion, uTestedMinorVersion, uTestedMicroVersion = [ int(s) for s in sTestedPythonVersion.split(".") ] auTestedMajorVersions.add(uTestedMajorVersion) if uMajorVersion == uTestedMajorVersion: bRunningInTestedMajorVersion = True if uMinorVersion == uTestedMinorVersion: if uMicroVersion == uTestedMicroVersion: # We are running in a tested Python version. bRunningInTestedVersion = True elif uMicroVersion < uTestedMicroVersion: # This application was tested in a later version, so the version we are running in is outdated. bRunningInOlderVersion = True elif uMinorVersion < uTestedMinorVersion: # This application was tested in a later version, so the version we are running in is outdated. bRunningInOlderVersion = True if not bRunningInTestedMajorVersion: asTestedMayorVersions = sorted(str(u) for u in auTestedMajorVersions) oConsole.fOutput( COLOR_ERROR, CHAR_ERROR, COLOR_NORMAL, " ", sApplicationName, " requires Python version ", faxListOutput(asTestedMayorVersions, "or", asTestedMayorVersions, COLOR_INFO, COLOR_NORMAL), COLOR_NORMAL, ".", ) sys.exit(guExitCodeInternalError) if not bRunningInTestedVersion: oConsole.fLock() try: oConsole.fOutput("┌───[", COLOR_WARNING, " Warning ", COLOR_NORMAL, "]", sPadding="─") oConsole.fOutput( "│ You are running a", "n older" if bRunningInOlderVersion else " newer", " version of Python (", COLOR_INFO, sPythonVersion, COLOR_NORMAL, ") in which this version of", ) oConsole.fOutput( "│ ", COLOR_INFO, sApplicationName, COLOR_NORMAL, " ", "was never tested" if bRunningInOlderVersion else "has not been tested yet", ".", ) oConsole.fOutput( "│ The following Python versions have been tested:", ) oConsole.fOutput( "│ ", faxListOutput(asTestedPythonVersions, "and", asTestedPythonVersions, COLOR_INFO, COLOR_NORMAL), COLOR_NORMAL, ".", ) if bRunningInOlderVersion: oConsole.fOutput( "│ Please update Python to the latest version!", ) else: oConsole.fOutput( "│ Please report this so ", sApplicationName, " can be tested with this version of Python at the following URL:", ) oConsole.fOutput( "│ ", COLOR_INFO | CONSOLE_UNDERLINE, sBugURL, ) oConsole.fOutput("└", sPadding="─") finally: oConsole.fUnlock() elif bRunningInOlderVersion: oConsole.fLock() try: oConsole.fOutput("┌───[", COLOR_WARNING, " Warning ", COLOR_NORMAL, "]", sPadding="─") oConsole.fOutput("│ You are running Python ", COLOR_INFO, sPythonVersion, COLOR_NORMAL, ", which is outdated.") oConsole.fOutput("│ Please update Python to the latest version!") oConsole.fOutput("└", sPadding="─") finally: oConsole.fUnlock()
def fOutputCurrentJITDebuggerSettings(): oConsole.fLock() try: oConsole.fOutput("┌───[", COLOR_INFO, " Current JIT Debugger ", COLOR_NORMAL, "]", sPadding="─") xCurrentJITDebuggerCommandLine = fxGetCurrentJITDebuggerCommandLine() if not fbIsProvided(xCurrentJITDebuggerCommandLine): oConsole.fOutput( "│ ", COLOR_INFO, CHAR_INFO, COLOR_NORMAL, "JIT debugger: ", COLOR_INFO, "None", COLOR_NORMAL, ".", ) elif xCurrentJITDebuggerCommandLine is None: oConsole.fOutput( "│ ", COLOR_ERROR, CHAR_ERROR, COLOR_NORMAL, " JIT debugger: ", COLOR_INFO, "Unknown", COLOR_NORMAL, " (unable to read registry).", ) else: sBugIdJITDebuggerCommandLineStartsWith = fsCreateBugIdCommandLine( ) if xCurrentJITDebuggerCommandLine.startswith( sBugIdJITDebuggerCommandLineStartsWith): oConsole.fOutput( "│ ", COLOR_OK, CHAR_OK, COLOR_NORMAL, " JIT debugger: ", COLOR_INFO, "BugId", COLOR_NORMAL, ".", ) sArguments = xCurrentJITDebuggerCommandLine[ len(sBugIdJITDebuggerCommandLineStartsWith) + 1:] oConsole.fOutput( "│ Arguments: ", COLOR_INFO, sArguments, ) else: oConsole.fOutput( "│ ", COLOR_WARNING, CHAR_WARNING, COLOR_NORMAL, " JIT debugger: ", COLOR_INFO, "Other", COLOR_NORMAL, ".", ) oConsole.fOutput( "│ Command line: ", COLOR_INFO, xCurrentJITDebuggerCommandLine, ) oConsole.fOutput("└", sPadding="─") finally: oConsole.fUnlock()
def fOutputUsageInformation(): asApplicationKeywords = list(ddxApplicationSettings_by_sKeyword.keys()) oConsole.fLock() try: fOutputLogo() axBoolean = [ "[=", COLOR_INFO, "true", COLOR_NORMAL, "|", COLOR_INFO, "false", COLOR_NORMAL, "]" ] oConsole.fOutput(COLOR_HILITE, "Usage:") oConsole.fOutput() oConsole.fOutput(" ", COLOR_INFO, "BugId.py", COLOR_NORMAL, " [", COLOR_INFO, "options", COLOR_NORMAL, "] <", COLOR_INFO, "target", COLOR_NORMAL, "> [", COLOR_INFO, "options", COLOR_NORMAL, "] [-- ", COLOR_INFO, "argument ", COLOR_NORMAL, "[", COLOR_INFO, "argument ", COLOR_NORMAL, "[", COLOR_INFO, "...", COLOR_NORMAL, "]]]") oConsole.fOutput() oConsole.fOutput(COLOR_HILITE, "Targets:") oConsole.fOutput(" ", COLOR_INFO, "\"path\\to\\binary.exe\"") oConsole.fOutput( " Start the given binary in the debugger with the given arguments." ) oConsole.fOutput(" ", COLOR_INFO, "--pids=pid[,pid[...]]") oConsole.fOutput( " Attach debugger to the process(es) provided in the list. The processes ", COLOR_HILITE, "must") oConsole.fOutput( " all have been suspended, as they will be resumed by the debugger." ) oConsole.fOutput( " Arguments cannot be provided for obvious reasons.") oConsole.fOutput(" ", COLOR_INFO, "--uwp-app=<package name>[!<application id>]") oConsole.fOutput( " Start and debug a Universal Windows Platform App identified by the given" ) oConsole.fOutput( " package name and application id. If no application id is provided and the" ) oConsole.fOutput( " package exposes only one if, it will default to that id. Note that only" ) oConsole.fOutput( " a single argument can be passed to a UWP App; additional arguments will be" ) oConsole.fOutput(" silently ignored.") oConsole.fOutput(" ", COLOR_INFO, "<known application keyword>") oConsole.fOutput( " BugId has a list of known targets that are identified by a keyword. You can" ) oConsole.fOutput( " use such a keyword to have BugId try to automatically find the binary or" ) oConsole.fOutput( " determine the package name and id for that application, optionally apply" ) oConsole.fOutput( " application specific settings and provide default arguments. This makes it" ) oConsole.fOutput( " easier to run these applications without having to manually provide these." ) oConsole.fOutput( " You can optioanlly override any default settings by providing them *after*" ) oConsole.fOutput( " the keyword. You can also provide the path to the application binary after" ) oConsole.fOutput( " the keyword to use a different binary than the one BugId automatically" ) oConsole.fOutput( " detects, or if BugId is unable to detect the binary on your system." ) oConsole.fOutput() oConsole.fOutput(COLOR_HILITE, "Options:") oConsole.fOutput(" ", COLOR_INFO, "-h", COLOR_NORMAL, ", ", COLOR_INFO, "--help") oConsole.fOutput(" This cruft.") oConsole.fOutput(" ", COLOR_INFO, "--version") oConsole.fOutput(" Show version information.") oConsole.fOutput(" ", COLOR_INFO, "--version-check") oConsole.fOutput(" Check for updates and show version information.") oConsole.fOutput(" ", COLOR_INFO, "--license") oConsole.fOutput(" Show license information.") oConsole.fOutput(" ", COLOR_INFO, "--license-update") oConsole.fOutput( " Download license updates and show license information.") oConsole.fOutput(" ", COLOR_INFO, "--arguments", COLOR_NORMAL, "=<", COLOR_INFO, "file path", COLOR_NORMAL, ">") oConsole.fOutput( " Load additional arguments from the provided value and insert them in place" ) oConsole.fOutput(" of this argument.") oConsole.fOutput(" ", COLOR_INFO, "-q", COLOR_NORMAL, ", ", COLOR_INFO, "--quiet", axBoolean) oConsole.fOutput( " Output only essential information. (default is \"false\")") oConsole.fOutput(" ", COLOR_INFO, "-v", COLOR_NORMAL, ", ", COLOR_INFO, "--verbose", axBoolean) oConsole.fOutput( " Output all commands send to cdb.exe and everything it outputs in return." ) oConsole.fOutput( " Note that -q and -v are not mutually exclusive. (default is \"false\")" ) oConsole.fOutput(" ", COLOR_INFO, "-p", COLOR_NORMAL, ", ", COLOR_INFO, "--pause", axBoolean) oConsole.fOutput( " Always wait for the user to press ENTER before terminating at the end." ) oConsole.fOutput(" (default is \"false\")") oConsole.fOutput(" ", COLOR_INFO, "-c", COLOR_NORMAL, ", ", COLOR_INFO, "--collateral", COLOR_NORMAL, "[=", COLOR_INFO, "number of bugs", COLOR_NORMAL, "]") oConsole.fOutput( " When the specified number of bugs is larger than 1 (default 5), BugId will" ) oConsole.fOutput( " go into \"collateral bug handling\" mode. This means that after certain" ) oConsole.fOutput( " access violation bugs are reported, it will attempt to \"fake\" that the" ) oConsole.fOutput( " instruction that caused the exception succeeded without triggering an" ) oConsole.fOutput( " exception. For read operations, it will set the destination register to a" ) oConsole.fOutput( " tainted value (0x41414141...). For write operations, it will simply step" ) oConsole.fOutput( " over the instruction. It will do this for up to the specified number of" ) oConsole.fOutput(" bugs.") oConsole.fOutput( " The upshot of this is that you can get an idea of what would happen if" ) oConsole.fOutput( " you were able to control the bad read/write operation. This can be usedful" ) oConsole.fOutput( " when determining if a particular vulnerability is theoretically exploitable" ) oConsole.fOutput( " or not. E.g. it might show that nothing else happens, that the application" ) oConsole.fOutput( " crashes unavoidably and immediately, both of which indicate that the issue" ) oConsole.fOutput( " is not exploitable. It might also show that reading from or writing to" ) oConsole.fOutput( " otherwise inaccessible parts of memory or controlling execution flow is" ) oConsole.fOutput( " potentially possible, indicating it is exploitable.") oConsole.fOutput(" ", COLOR_INFO, "-d", COLOR_NORMAL, ", ", COLOR_INFO, "--dump", axBoolean) oConsole.fOutput( " Save a mini crash dump when a crash is detected.") oConsole.fOutput(" ", COLOR_INFO, "--full-dump", axBoolean) oConsole.fOutput( " Save a full crash dump when a crash is detected.") oConsole.fOutput(" ", COLOR_INFO, "-f", COLOR_NORMAL, ", ", COLOR_INFO, "--fast", axBoolean) oConsole.fOutput( " Create no HTML report, do not use symbols. This is an alias for:" ) oConsole.fOutput(" ", COLOR_INFO, "--bGenerateReportHTML=false") oConsole.fOutput(" ", COLOR_INFO, "--cBugId.asSymbolServerURLs=[]") oConsole.fOutput(" ", COLOR_INFO, "--cBugId.bUse_NT_SYMBOL_PATH=false") oConsole.fOutput(" ", COLOR_INFO, "-I", COLOR_NORMAL, " [", COLOR_INFO, "arguments", COLOR_NORMAL, "]") oConsole.fOutput( " Install as the default JIT debugger on the system. This allows BugId to" ) oConsole.fOutput( " generate a report whenever an application crashes.") oConsole.fOutput( " All arguments after -I will be passed to BugId whenever it is started as" ) oConsole.fOutput( " the JIT debugger. It might be useful to add arguments such as \"--pause\"" ) oConsole.fOutput( " to leave the BugId window open after it generated a report, \"--full-dump\"" ) oConsole.fOutput( " to generate a full memory dump and \"--reports=<path>\" to have the reports" ) oConsole.fOutput( " stored in a specific folder. If you do not provide \"--reports\", it will" ) oConsole.fOutput( " be added automatically to make sure the reports are saved in a folder that" ) oConsole.fOutput( " BugId can write to, and which you can easily find.") oConsole.fOutput(" Here's what I normally use:") oConsole.fOutput( " ", COLOR_HILITE, "BugId -I --collateral=10 \"--reports=%USERPROFILE%\\BugId reports\" --full-dump" ) oConsole.fOutput(" ", COLOR_INFO, "--jit") oConsole.fOutput( " Show details on the currently installed JIT debugger.") oConsole.fOutput(" ", COLOR_INFO, "--isa", COLOR_NORMAL, "=", COLOR_INFO, "x86", COLOR_NORMAL, "|", COLOR_INFO, "x64") oConsole.fOutput( " Use the x86 or x64 version of cdb to debug the application. The default is" ) oConsole.fOutput( " to use the ISA* of the OS. Applications build to run on x86 systems can be" ) oConsole.fOutput( " debugged using the x64 version of cdb, and you are strongly encouraged to " ) oConsole.fOutput( " do so. But you can use the x86 debugger to debug x86 application if you" ) oConsole.fOutput(" want to. (ISA = Instruction Set Architecture)") oConsole.fOutput(" ", COLOR_INFO, "-r", COLOR_NORMAL, ", ", COLOR_INFO, "--repeat", COLOR_NORMAL, "[=", COLOR_INFO, "number of loops", COLOR_NORMAL, "]") oConsole.fOutput( " Restart the application to run another test as soon as the application is" ) oConsole.fOutput( " terminated. Useful when testing the reliability of a repro, detecting the" ) oConsole.fOutput( " various crashes a non-deterministic repro can cause or while making " ) oConsole.fOutput( " modifications to the repro in order to test how they affect the crash." ) oConsole.fOutput( " A statistics file is created or updated after each run that contains the" ) oConsole.fOutput( " number of occurances of each Bug Id that was detected. If a number is" ) oConsole.fOutput( " provided, the application will be run that many times. Otherwise the" ) oConsole.fOutput(" application will be run indefinitely.") oConsole.fOutput(" ", COLOR_INFO, "--symbols", COLOR_NORMAL, "=", COLOR_INFO, "path\\to\\symbols\\folder") oConsole.fOutput( " Use the given path as a local symbol folder in addition to the symbol paths" ) oConsole.fOutput( " specified in dxConfig. You can provide this option multiple times to add" ) oConsole.fOutput( " as many additional local symbol paths as needed.") oConsole.fOutput(" ", COLOR_INFO, "--reports", COLOR_NORMAL, "=", COLOR_INFO, "path\\to\\reports\\folder") oConsole.fOutput( " Store reports in the given path. Optional cdb output and crash dumps are" ) oConsole.fOutput(" stored in the same location.") oConsole.fOutput() oConsole.fOutput( " Options also include any of the settings in dxConfig.py; you can specify them" ) oConsole.fOutput(" using ", COLOR_INFO, "--", COLOR_NORMAL, "[", COLOR_INFO, "name", COLOR_NORMAL, "]=[", COLOR_INFO, "JSON value", COLOR_NORMAL, "]. Here are some examples:") oConsole.fOutput(" ", COLOR_INFO, "--bGenerateReportHTML=false") oConsole.fOutput( " Do not save a HTML formatted crash report. This should make BugId run" ) oConsole.fOutput( " faster and use less RAM, as it does not need to gather and process the" ) oConsole.fOutput(" information needed for the HTML report.") oConsole.fOutput( " If you only need to confirm a crash can be reproduced, you may want to use" ) oConsole.fOutput( " this: it can make the process of analyzing a crash a lot faster. But if" ) oConsole.fOutput( " no local or cached symbols are available, you'll get less information" ) oConsole.fOutput(" ", COLOR_INFO, "\"--sReportFolderPath=\\\"BugId\\\"\"") oConsole.fOutput( " Save report to the specified folder, in this case \"BugId\". The quotes" ) oConsole.fOutput( " mess is needed because of the Windows quirck explained below." ) oConsole.fOutput(" The remaining dxConfig settings are:") for sSettingName in sorted(dxConfig.keys()): if sSettingName not in [ "bGenerateReportHTML", "sReportFolderPath", "cBugId" ]: xSettingValue = dxConfig[sSettingName] oConsole.fOutput(" ", COLOR_INFO, "--", sSettingName, COLOR_NORMAL, " (default value: ", COLOR_INFO, str(xSettingValue), COLOR_NORMAL, ")") oConsole.fOutput(" See ", COLOR_INFO, "dxConfig.py", COLOR_NORMAL, " for details on each setting.") oConsole.fOutput() oConsole.fOutput( " You can also adjust cBugId specific settings, such as:") oConsole.fOutput( " ", COLOR_INFO, "--cBugId.asSymbolServerURLs=[\"http://msdl.microsoft.com/download/symbols\"]" ) oConsole.fOutput( " Use http://msdl.microsoft.com/download/symbols as a symbol server." ) oConsole.fOutput(" ", COLOR_INFO, "--cBugId.asSymbolCachePaths=[\"C:\\Symbols\"]") oConsole.fOutput(" Use C:\\Symbols to cache symbol files.") oConsole.fOutput(" See ", COLOR_INFO, "cBugId\\dxConfig.py", COLOR_NORMAL, " for details on all available settings.") oConsole.fOutput( " All values must be valid JSON of the appropriate type. No checks are made to" ) oConsole.fOutput( " ensure this! Providing illegal values may result in exceptions at any time" ) oConsole.fOutput(" during execution. You have been warned!") oConsole.fOutput() oConsole.fOutput( " Note that you may need to do a bit of \"quote-juggling\" because Windows likes" ) oConsole.fOutput( " to eat quotes for no obvious reason. So, if you want to specify --a=\"b\", you" ) oConsole.fOutput( " will need to use \"--a=\\\"b\\\"\", or BugId will see --a=b and `b` is not valid" ) oConsole.fOutput(" JSON.") oConsole.fOutput() oConsole.fOutput(COLOR_HILITE, "Known application keywords:") asLine = [" "] uLineLength = 2 for sApplicationKeyword in asApplicationKeywords: if uLineLength > 2: if uLineLength + 2 + len(sApplicationKeyword) + 2 > 80: asLine += [COLOR_NORMAL, ","] oConsole.fOutput(*asLine) asLine = [" "] uLineLength = 2 else: asLine += [COLOR_NORMAL, ", "] uLineLength += 2 asLine += [COLOR_INFO, sApplicationKeyword] uLineLength += len(sApplicationKeyword) asLine += [COLOR_NORMAL, "."] oConsole.fOutput(*asLine) oConsole.fOutput() oConsole.fOutput( " Run ", COLOR_INFO, "BugId.py application?", COLOR_NORMAL, " for an overview of the application specific command") oConsole.fOutput(" line arguments and settings.") oConsole.fOutput() oConsole.fOutput(COLOR_HILITE, "Exit codes:") oConsole.fOutput(" ", COLOR_INFO, "0", COLOR_NORMAL, " = BugId successfully ran the application ", CONSOLE_UNDERLINE, "without detecting a bug", COLOR_NORMAL, ".") oConsole.fOutput(" ", COLOR_INFO, "1", COLOR_NORMAL, " = BugId successfully ran the application and ", CONSOLE_UNDERLINE, "detected a bug", COLOR_NORMAL, ".") oConsole.fOutput( " ", COLOR_ERROR, "2", COLOR_NORMAL, " = BugId was unable to parse the command-line arguments provided." ) oConsole.fOutput( " ", COLOR_ERROR, "3", COLOR_NORMAL, " = BugId ran into an internal error: please report the details!") oConsole.fOutput( " ", COLOR_ERROR, "4", COLOR_NORMAL, " = BugId was unable to start or attach to the application.") oConsole.fOutput(" ", COLOR_ERROR, "5", COLOR_NORMAL, " = You do not have a valid license.") finally: oConsole.fUnlock()
def fOutputLicenseInformation(bUpdateIfNeeded=False): # Read product details for rs and all modules it uses. aoProductDetails = mProductDetails.faoGetProductDetailsForAllLoadedModules( ) o0MainProductDetails = mProductDetails.fo0GetProductDetailsForMainModule() oConsole.fLock() try: aoLicenses = [] asProductNamesWithoutLicenseRequirement = [] asLicensedProductNames = [] asProductNamesInTrial = [] asUnlicensedProductNames = [] for oProductDetails in aoProductDetails: if not oProductDetails.bRequiresLicense: asProductNamesWithoutLicenseRequirement.append( oProductDetails.sProductName) elif oProductDetails.o0License: if oProductDetails.o0License not in aoLicenses: aoLicenses.append(oProductDetails.o0License) asLicensedProductNames.append(oProductDetails.sProductName) elif oProductDetails.bHasTrialPeriod and oProductDetails.bInTrialPeriod: asProductNamesInTrial.append(oProductDetails.sProductName) else: asUnlicensedProductNames.append(oProductDetails.sProductName) if o0MainProductDetails and o0MainProductDetails.sb0LicenseServerURL is not None: oLicenseServer = mProductDetails.cLicenseServer( o0MainProductDetails.sb0LicenseServerURL) uCheckedLicenseCounter = 0 aoUpdatedLicenses = [] for oLicense in aoLicenses: oConsole.fProgressBar( uCheckedLicenseCounter * 1.0 / len(aoLicenses), "Checking license %s with server..." % oLicense.sLicenseId, ) sLicenseServerError = oLicense.fsCheckWithServerAndGetError( oLicenseServer, bForceCheck=True) sServerURL = str(o0MainProductDetails.sb0LicenseServerURL, "ascii", "strict") if sLicenseServerError: oConsole.fOutput( COLOR_ERROR, CHAR_ERROR, COLOR_NORMAL, " License check for ", COLOR_INFO, oLicense.sLicenseId, COLOR_NORMAL, " on server ", COLOR_INFO, sServerURL, COLOR_NORMAL, " failed:", ) oConsole.fOutput( " ", COLOR_INFO, sLicenseServerError, ) uCheckedLicenseCounter += 1 if oLicense.bMayNeedToBeUpdated and bUpdateIfNeeded: oConsole.fProgressBar( uCheckedLicenseCounter * 1.0 / len(aoLicenses), "Downloading updated license %s from server..." % oLicense.sLicenseId, ) oUpdatedLicense = oLicenseServer.foDownloadUpdatedLicense( oLicense) oConsole.fOutput( COLOR_OK, CHAR_OK, COLOR_NORMAL, " Downloaded updated license ", COLOR_INFO, oLicense.sLicenseId, COLOR_NORMAL, " from server ", COLOR_INFO, str(oLicenseServer.sbServerURL, "ascii", "strict"), COLOR_NORMAL, ".", ) aoUpdatedLicenses.append(oUpdatedLicense) if len(aoUpdatedLicenses) > 0: for oProductDetails in aoProductDetails: if oProductDetails.sb0LicenseServerURL is None: continue # No need for a license == do not store license aoUpdatedLicensesForThisProduct = [ oUpdatedLicense for oUpdatedLicense in aoUpdatedLicenses if oProductDetails.sProductName in oUpdatedLicense.asProductNames ] mProductDetails.fWriteLicensesToProductFolder( aoUpdatedLicensesForThisProduct, oProductDetails) oConsole.fOutput( COLOR_OK, CHAR_OK, COLOR_NORMAL, " Saved ", COLOR_INFO, str(len(aoUpdatedLicensesForThisProduct)), COLOR_NORMAL, " updated license", "" if len(aoUpdatedLicensesForThisProduct) == 1 else "s", " for product ", COLOR_INFO, oProductDetails.sProductName, COLOR_NORMAL, " in folder ", COLOR_INFO, oProductDetails.sInstallationFolderPath, COLOR_NORMAL, ".", ) if f0OutputLogo: f0OutputLogo() oConsole.fOutput( "┌───[", COLOR_HILITE, " License information ", COLOR_NORMAL, "]", sPadding="─", ) if aoLicenses: oConsole.fOutput( "│ ", COLOR_OK, CHAR_OK, COLOR_NORMAL, " This system uses system id ", COLOR_INFO, mProductDetails.fsGetSystemId(), COLOR_NORMAL, " with the license server.", ) oConsole.fOutput( "├", sPadding="─", ) for oLicense in aoLicenses: oConsole.fOutput( "│ ", COLOR_OK, CHAR_OK, COLOR_NORMAL, " License ", COLOR_INFO, oLicense.sLicenseId, COLOR_NORMAL, " covers ", COLOR_INFO, oLicense.sUsageTypeDescription, COLOR_NORMAL, " by ", COLOR_INFO, oLicense.sLicenseeName, COLOR_NORMAL, " of ", COLOR_INFO, oLicense.asProductNames[0], COLOR_NORMAL, " on ", COLOR_INFO, str(oLicense.uLicensedInstances), COLOR_NORMAL, " machine", "s" if oLicense.uLicensedInstances != 1 else "", ".", ) oConsole.fOutput( "│ Covered products: ", faxListOutput(oLicense.asProductNames, "and", oLicense.asProductNames, COLOR_INFO, COLOR_NORMAL, COLOR_NORMAL), COLOR_NORMAL, ".", ) oConsole.fOutput( "│ License source: ", COLOR_INFO, oLicense.sLicenseSource, COLOR_NORMAL, ".", ) if asProductNamesInTrial: oConsole.fOutput( "│ ", COLOR_WARNING, CHAR_WARNING, COLOR_NORMAL, " A ", COLOR_INFO, "trial period", COLOR_NORMAL, " is active for the following product", "s" if len(asProductNamesInTrial) > 1 else "", ":", ) oConsole.fOutput( "│ ", faxListOutput(asProductNamesInTrial, "and", asProductNamesInTrial, COLOR_INFO, COLOR_NORMAL, COLOR_NORMAL), COLOR_NORMAL, ".", ) if asProductNamesWithoutLicenseRequirement: oConsole.fOutput( "│ ", COLOR_OK, CHAR_OK, " ", COLOR_INFO, "No license", COLOR_NORMAL, " is required to use the following product", "s" if len(asProductNamesWithoutLicenseRequirement) > 1 else "", ":", ) oConsole.fOutput( "│ ", faxListOutput(asProductNamesWithoutLicenseRequirement, "and", [], COLOR_INFO, COLOR_NORMAL, COLOR_NORMAL), COLOR_NORMAL, ".", ) if asUnlicensedProductNames: oConsole.fOutput( "│ ", COLOR_ERROR, CHAR_ERROR, COLOR_NORMAL, " ", COLOR_INFO, "No valid license", COLOR_NORMAL, " was found and ", COLOR_INFO, "the trial period has been exceeded", COLOR_NORMAL, " for the following product", "s" if len(asUnlicensedProductNames) > 1 else "", ":", ) oConsole.fOutput( "│ ", faxListOutput(asUnlicensedProductNames, "and", asUnlicensedProductNames, COLOR_INFO, COLOR_NORMAL, COLOR_NORMAL), COLOR_NORMAL, ".", ) (asLicenseErrors, asLicenseWarnings ) = mProductDetails.ftasGetLicenseErrorsAndWarnings() if asLicenseErrors: oConsole.fOutput("├───[", COLOR_ERROR, " Software license error ", COLOR_NORMAL, "]", sPadding="─") for sLicenseError in asLicenseErrors: oConsole.fOutput("│ ", COLOR_ERROR, CHAR_ERROR, COLOR_INFO, " ", sLicenseError) if asLicenseWarnings: oConsole.fOutput("├───[", COLOR_WARNING, " Software license warning ", COLOR_NORMAL, "]", sPadding="─") for sLicenseWarning in asLicenseWarnings: oConsole.fOutput("│ ", COLOR_WARNING, CHAR_WARNING, COLOR_INFO, " ", sLicenseWarning) oConsole.fOutput("└", sPadding="─") finally: oConsole.fUnlock()