Пример #1
0
def consoleRipper(writeDirectory):
    # Rip audio to to WAV or FLAC (depending on dBpoweramps settings in default profile)
    # Uses the bespoke dBpoweramp console ripper which was developed at request of KB 
    # dBpoweramp\kb-nl-consolerip.exe" --drive="D" --log=E:\cdBatchesTest\testconsolerip\log.txt --path=E:\cdBatchesTest\testconsolerip\
    #    

    # NOTE: logFile doesn't offer anything that's not in the secure extraction log
    # So it is simply discarded after ripping
    logFile = os.path.join(config.tempDir,shared.randomString(12) + ".log")
    secureExtractionLogFile = os.path.join(writeDirectory, "dbpoweramp.log")
       
    args = [config.dBpowerampConsoleRipExe]
    args.append("".join(["--drive=", config.cdDriveLetter]))
    args.append("".join(["--log=", logFile]))
    args.append("".join(["--path=", writeDirectory]))
  
    # Command line as string (used for logging purposes only)
    cmdStr = " ".join(args)
        
    status, out, err = shared.launchSubProcess(args)
    
    with io.open(logFile, "r", encoding="utf-8-sig") as fLog:
        log = fLog.read()
    fLog.close()
    
    # Remove log file
    os.remove(logFile)
    
    # Read Secure Extraction log and convert to UTF-8
    with io.open(secureExtractionLogFile, "r", encoding="utf-16") as fSecureExtractionLogFile:
        text = fSecureExtractionLogFile.read()
    fSecureExtractionLogFile.close()
    with io.open(secureExtractionLogFile, "w", encoding="utf-8") as fSecureExtractionLogFile:
        fSecureExtractionLogFile.write(text)
    fSecureExtractionLogFile.close()
    
    # All results to dictionary
    dictOut = {}
    dictOut["cmdStr"] = cmdStr
    dictOut["status"] = status
    dictOut["stdout"] = out
    dictOut["stderr"] = err
    dictOut["log"] = log
    
    return(dictOut)
Пример #2
0
def getDrives():
    # Returns list of all optical drives
    # cd-info command line:
    # cd-info -l

    args = [config.cdInfoExe]
    args.append("-l")

    # Command line as string (used for logging purposes only)
    cmdStr = " ".join(args)

    status, out, err = shared.launchSubProcess(args)

    # Output lines to list
    outAsList = out.splitlines()

    # Set up list for storing identified drives
    drives = []

    # Locate track list and analysis report in cd-info output
    startIndexDevicesList = shared.index_startswith_substring(
        outAsList, "list of devices found:")

    # Parse devices list and store Drive entries to list
    for i in range(startIndexDevicesList + 1, len(outAsList), 1):
        thisLine = outAsList[i]
        if thisLine.startswith("Drive") == True:
            thisDrive = thisLine.split("\\\\.\\")
            driveLetter = thisDrive[1].strip(":\n")
            drives.append(driveLetter)

    # Main results to dictionary
    dictOut = {}
    dictOut["cmdStr"] = cmdStr
    dictOut["drives"] = drives
    dictOut["status"] = status
    dictOut["stdout"] = out
    dictOut["stderr"] = err

    return (dictOut)
Пример #3
0
def load():
    logFile = os.path.join(config.tempDir, shared.randomString(12) + ".log")
    errorFile = os.path.join(config.tempDir, shared.randomString(12) + ".err")

    args = [config.loadExe]
    args.append("--drive=" + config.cdDriveLetter)
    args.append("--rejectifnodisc")
    args.append("--logfile=" + logFile)
    args.append("--passerrorsback=" + errorFile)

    # Command line as string (used for logging purposes only)
    cmdStr = " ".join(args)

    status, out, err = shared.launchSubProcess(args)
    fLog = open(logFile, 'r')
    fErr = open(errorFile, 'r')
    log = fLog.read()
    errors = fErr.read()

    # Convert log and errors from little-Endian UTF-16 to UTF-8
    logUTF8 = log.encode('utf-8').decode('utf-16le')
    errorsUTF8 = errors.encode('utf-8').decode('utf-16le')

    fLog.close()
    fErr.close()
    os.remove(logFile)
    os.remove(errorFile)

    # All results to dictionary
    dictOut = {}
    dictOut["cmdStr"] = cmdStr
    dictOut["status"] = status
    dictOut["stdout"] = out
    dictOut["stderr"] = err
    dictOut["log"] = logUTF8
    dictOut["errors"] = errorsUTF8

    return (dictOut)
Пример #4
0
def getCarrierInfo(writeDirectory):
    # Determine carrier type and number of sessions on carrier
    # cd-info command line:
    # cd-info -C d: --no-header --no-device-info --no-cddb --dvd

    ## TEST
    #config.cdInfoExe = "C:/Users/jkn010/iromlab/tools/libcdio/win64/cd-info.exe"
    #config.cdDriveLetter = "D"
    ## TEST

    cdInfoLogFile = os.path.join(writeDirectory, "cd-info.log")

    args = [config.cdInfoExe]
    args.append("-C")
    args.append("".join([config.cdDriveLetter, ":"]))
    args.append("--no-header")
    args.append("--no-device-info")
    args.append("--no-disc-mode")
    args.append("--no-cddb")
    args.append("--dvd")

    # Command line as string (used for logging purposes only)
    cmdStr = " ".join(args)

    status, out, err = shared.launchSubProcess(args)

    # Output lines to list
    outAsList = out.splitlines()

    # Set up dictionary and list for storing track list and analysis report
    trackList = []
    analysisReport = []

    # Locate track list and analysis report in cd-info output
    startIndexTrackList = shared.index_startswith_substring(
        outAsList, "CD-ROM Track List")
    startIndexAnalysisReport = shared.index_startswith_substring(
        outAsList, "CD Analysis Report")

    # Parse track list and store interesting bits in dictionary
    for i in range(startIndexTrackList + 2, startIndexAnalysisReport - 1, 1):
        thisTrack = outAsList[i]
        if thisTrack.startswith("++") == False:
            thisTrack = thisTrack.split(": ")
            trackNumber = int(thisTrack[0].strip())
            trackDetails = thisTrack[1].split()
            trackMSFStart = trackDetails[0]  # Minute:Second:Frame
            trackLSNStart = trackDetails[1]  # Logical Sector Number
            trackType = trackDetails[2]
            trackProperties = {}
            trackProperties['trackNumber'] = trackNumber
            trackProperties['trackMSFStart'] = trackMSFStart
            trackProperties['trackLSNStart'] = trackLSNStart
            trackProperties['trackType'] = trackType
            trackList.append(trackProperties)

    # Flags for presence of audio / data tracks
    containsAudio = False
    containsData = False
    dataTrackLSNStart = '0'

    for track in trackList:
        if track['trackType'] == 'audio':
            containsAudio = True
        if track['trackType'] == 'data':
            containsData = True
            dataTrackLSNStart = track['trackLSNStart']

    # Parse analysis report
    for i in range(startIndexAnalysisReport + 1, len(outAsList), 1):
        thisLine = outAsList[i]
        if thisLine.startswith("++") == False:
            analysisReport.append(thisLine)

    # Flags for CD/Extra / multisession / mixed-mode
    # Note that single-session mixed mode CDs are erroneously reported as
    # multisession by libcdio. See: http://savannah.gnu.org/bugs/?49090#comment1

    cdExtra = shared.index_startswith_substring(analysisReport,
                                                "CD-Plus/Extra") != -1
    multiSession = shared.index_startswith_substring(analysisReport,
                                                     "session #") != -1
    mixedMode = shared.index_startswith_substring(analysisReport,
                                                  "mixed mode CD") != -1

    # Write cd-info output to log file
    with io.open(cdInfoLogFile, "w", encoding="utf-8") as fCdInfoLogFile:
        for line in outAsList:
            fCdInfoLogFile.write(line + "\n")
    fCdInfoLogFile.close()

    # Main results to dictionary
    dictOut = {}
    dictOut["cmdStr"] = cmdStr
    dictOut["cdExtra"] = cdExtra
    dictOut["multiSession"] = multiSession
    dictOut["mixedMode"] = mixedMode
    dictOut["containsAudio"] = containsAudio
    dictOut["containsData"] = containsData
    dictOut["dataTrackLSNStart"] = dataTrackLSNStart
    dictOut["status"] = status
    dictOut["stdout"] = out
    dictOut["stderr"] = err

    return (dictOut)
Пример #5
0
def verifyAudioFile(audioFile, format):
    # Verify integrity of an audio file (check for missing / truncated bytes)

    if format == "wav":
        # Check with shntool

        args = [config.shntoolExe]
        #args = ["C:/Users/jkn010/iromlab/tools/shntool/shntool.exe"]
        args.append("info")
        args.append(audioFile)

        # Command line as string (used for logging purposes only)
        cmdStr = " ".join(args)

        status, out, err = shared.launchSubProcess(args)

        # Output lines to list
        outAsList = out.splitlines()
        noLines = len(outAsList)

        # Set up dictionary for storing values on reported problems
        problems = {}
        problemsAsList = []

        # Locate problems report
        startIndexProblems = shared.index_startswith_substring(
            outAsList, "Possible problems:")

        # Parse problems list and store as dictionary
        for i in range(startIndexProblems + 1, noLines, 1):
            thisLine = outAsList[i]
            lineAsList = thisLine.split(":")
            problemName = lineAsList[0].strip()
            problemValue = lineAsList[1].strip()
            problems[problemName] = problemValue
            problemsAsList.append(thisLine.strip())
        try:
            if problems["Inconsistent header"] != "no":
                isOK = False
            elif problems["File probably truncated"] != "no":
                isOK = False
            elif problems["Junk appended to file"] != "no":
                isOK = False
            else:
                isOK = True
        except KeyError:
            isOK = False

        # Add file reference as first element of errors list (used for logging only)
        problemsAsList.insert(0, "File: " + audioFile)
        return (isOK, status, problemsAsList)

    elif format == "flac":
        # Check with flac

        args = [config.flacExe]
        #args = ["C:/Users/jkn010/iromlab/tools/flac/win64/flac.exe"]
        args.append("-s")
        args.append("-t")
        args.append(audioFile)

        # Command line as string (used for logging purposes only)
        cmdStr = " ".join(args)

        status, out, err = shared.launchSubProcess(args)

        # Output lines to list (flac output is sent to stderr!)
        errAsList = err.splitlines()

        if (len(errAsList)) == 0:
            # No errors encountered
            isOK = True
        else:
            isOK = False

        # Add file reference as first element of errors list (used for logging only)
        errAsList.insert(0, "File: " + audioFile)
        return (isOK, status, errAsList)
Пример #6
0
def extractData(writeDirectory, session, dataTrackLSNStart):
    # IsoBuster /d:i /ei:"E:\nimbieTest\myDiskIB.iso" /et:u /ep:oea /ep:npc /c /m /nosplash /s:1 /l:"E:\nimbieTest\ib.log"

    # Temporary name for ISO file; base name
    isoFileTemp = os.path.join(writeDirectory, "disc.iso")
    #isoFile = os.path.join(writeDirectory, isoName)
    logFile = os.path.join(writeDirectory, "isobuster.log")

    args = [config.isoBusterExe]
    args.append("".join(["/d:", config.cdDriveLetter, ":"]))
    args.append("".join(["/ei:", isoFileTemp]))
    args.append("/et:u")
    args.append("/ep:oea")
    args.append("/ep:npc")
    args.append("/c")
    args.append("/m")
    args.append("/nosplash")
    args.append("".join(["/s:", str(session)]))
    args.append("".join(["/l:", logFile]))

    # Command line as string (used for logging purposes only)
    cmdStr = " ".join(args)

    status, out, err = shared.launchSubProcess(args)

    # Open and read log file
    with io.open(logFile, "r", encoding="cp1252") as fLog:
        log = fLog.read()
    fLog.close()

    # Rewrite as UTF-8
    with io.open(logFile, "w", encoding="utf-8") as fLog:
        fLog.write(log)
    fLog.close()

    # Run isolyzer ISO
    try:
        isolyzerResult = isolyzer.processImage(isoFileTemp, dataTrackLSNStart)

        # Isolyzer status
        isolyzerSuccess = isolyzerResult.find('statusInfo/success').text
        # Is ISO image smaller than expected (if True, this indicates the image may be truncated)
        imageTruncated = isolyzerResult.find('tests/smallerThanExpected').text
        # Volume identifier from ISO's Primary Volume Descriptor
        volumeIdentifier = isolyzerResult.find(
            'properties/primaryVolumeDescriptor/volumeIdentifier').text.strip(
            )
        if volumeIdentifier != '':
            # Rename ISO image using volumeIdentifier as a base name
            # Any spaces in volumeIdentifier are replaced with dashes
            isoFile = os.path.join(writeDirectory,
                                   volumeIdentifier.replace(' ', '-') + '.iso')
            os.rename(isoFileTemp, isoFile)

    except IOError or AttributeError:
        volumeIdentifier = ''
        isolyzerSuccess = False
        imageTruncated = True

    # TODO: for added security we could also verify the ISO's MD5 against MD5 of physical disc. But this
    # is slow + implementation under Windows will be ugly (with possible dependency on Cygwin because
    # not clear if Windows supports Unix-syle device paths)

    # All results to dictionary
    dictOut = {}
    dictOut["cmdStr"] = cmdStr
    dictOut["status"] = status
    dictOut["stdout"] = out
    dictOut["stderr"] = err
    dictOut["log"] = log
    dictOut["volumeIdentifier"] = volumeIdentifier
    dictOut["isolyzerSuccess"] = isolyzerSuccess
    dictOut["imageTruncated"] = imageTruncated

    return (dictOut)