Ejemplo n.º 1
0
 def _stringTimeToIntegerTimeInSeconds(self, stringTime):
     integerTime = 0
     # Multiplier if we are in seconds, minutes or hours
     unitMultiplier = 1
     # Multiplier according to the position of the figures in the number
     decimalMultiplier = 1
     for idxCharForward in range(len(stringTime)):
         # Browse the string in reverse order
         idxChar = len(stringTime)-idxCharForward - 1
         char = stringTime[idxChar]
         if (char >= "0" and char <= "9"):
             figure = int(char)
             integerTime = integerTime + \
                 (unitMultiplier * decimalMultiplier * figure)
             # For the next step (if it is a figure and not ":" or out of range), add a power of 10
             # Do not change the unit
             decimalMultiplier = 10*decimalMultiplier
         else:
             if (char == ":"):
                 # Reset decimalMultiplier for next figure
                 decimalMultiplier = 1
                 # Unit will change on next figure
                 # Seconds to minutes and minutes to hours have the same multiplier
                 unitMultiplier = 60*unitMultiplier
             else:
                 logPrint.printError(
                     char + " is not a figure or a comma, it is not possible to convert the time "+stringTime+" in seconds. Exiting.")
                 exit(-6)
     return integerTime
Ejemplo n.º 2
0
    def _findLineZero(self):
        lineNb = 0
        # Flag to stop the search for 0:00
        isLineAtTimeZero = False

        logPrint.printLog("Parsing the description field")

        for line in self.descriptionLinesList:
            if (not isLineAtTimeZero):
                # Not find yet: perform the search
                idxReturnedFromFind = line.find("0:00")
                if idxReturnedFromFind != -1:
                    # "0:00" found. We store the line number and the character index
                    if idxReturnedFromFind > 0:
                        # Consolidate: check again if idxReturnedFromFind>0, i.e. if it is really 00:00 and not for example 10:00
                        isLineAtTimeZero = self._checkIfDetectedZeroIsReallyZero(
                            line, idxReturnedFromFind)
                    else:
                        # 0:00 at index 0 is for sure a time zero
                        isLineAtTimeZero = True
                    if isLineAtTimeZero:
                        # self.idxCharZeroZero = idxReturnedFromFind
                        self.lineNbZeroZero = lineNb
                lineNb = lineNb+1
        if not isLineAtTimeZero:
            logPrint.printError("0:00 not found.")

        return isLineAtTimeZero
Ejemplo n.º 3
0
def main(outputFilePath, argv):
    prefix = ""

    youtubeApiInst = youtubeApiWrapper(sys.argv[1])
    descrFromYoutubeApi = youtubeApiInst.getDescriptionField()
    # descriptionParser accepts only list of str
    descrListFromYoutubeApi = descrFromYoutubeApi.splitlines()

    # First attempt of chapter parsing using what Youtube API returned
    descriptionParserInstFromYoutube = descriptionParser(
        descrListFromYoutubeApi)
    succesfullParsing = descriptionParserInstFromYoutube.parse()
    if (not succesfullParsing):
        logPrint.printInfo(
            "Another attempt can be given using pasted chapter list.")
        # Another parsing is attempted using stdin
        logPrint.printInfo(
            "Copy/paste the description list you want, then hit Ctrl+Z")
        # returns a list of str
        descrListFromCopyPaste = sys.stdin.readlines()
        # strip this line from "\n"
        strippedDescrListFromCopyPaste = [
            "" for idx in range(len(descrListFromCopyPaste))
        ]
        for idx in range(len(descrListFromCopyPaste)):
            strippedDescrListFromCopyPaste[idx] = descrListFromCopyPaste[
                idx].strip(" \n")
        # Create a new descriptionParser with the pasted list stripped from the final \n
        descriptionParserInstFromCopyPaste = descriptionParser(
            strippedDescrListFromCopyPaste)
        succesfullParsing = descriptionParserInstFromCopyPaste.parse()
        if (not succesfullParsing):
            logPrint.printError("Second attempt failed. Exiting.")
            exit(-5)
        else:
            chaptersMatrix = descriptionParserInstFromCopyPaste.getChaptersMatrix(
            )
    else:
        chaptersMatrix = descriptionParserInstFromYoutube.getChaptersMatrix()

    if len(sys.argv) == 3:
        prefix = sys.argv[2]
        logPrint.printLog(
            "The prefix \"" + prefix +
            "\" read from the program's arguments, will be added before each title."
        )
    else:
        prefix = ""
        logPrint.printLog("No prefix read from the program's arguments.")

    # Instantiate musicDisplayer to launch a timer and print the correct music name
    musicDisplayerInst = musicDisplayer(outputFilePath, chaptersMatrix, prefix)

    # Launch the timer
    musicDisplayerInst.start()
Ejemplo n.º 4
0
 def _buildPublicChaptersMatrix(self):
     returnStatus = True
     self.publicChaptersMatrix = np.empty(
         (self.chaptersMatrixSize, 2), dtype=object)
     previousTimeInSeconds = -1
     for idxMatrix in range(self.chaptersMatrixSize):
         timeinSeconds = self._stringTimeToIntegerTimeInSeconds(
             self.chaptersMatrix[idxMatrix, 0])
         if timeinSeconds < previousTimeInSeconds:
             # Something went wrong and the matrix is not in crescent order
             logPrint.printError(
                 self.chaptersMatrix[idxMatrix, 0] + " is smaller than the previous time, "+self.chaptersMatrix[idxMatrix-1, 0]+", the matrix is not ordered in a crescent order.")
             returnStatus = False
         self.publicChaptersMatrix[idxMatrix, 0] = timeinSeconds
         self.publicChaptersMatrix[idxMatrix,
                                   1] = self.chaptersMatrix[idxMatrix, 1]
     return returnStatus
Ejemplo n.º 5
0
 def __init__(self, message):
     self.message = message + ". Exiting."
     logPrint.printError(message)
     exit(-2)
Ejemplo n.º 6
0
    def _parseChapterList(self):
        idxSplitted = 0
        idxOfZeroInSplittedLine = -1
        line = self.descriptionLinesList[self.lineNbZeroZero]
        splittedLineList = re.split(r'([0-9:]+:[0-9:]+)', line)
        for splittedWord in splittedLineList:
            if re.search(r'[0-9:]+:[0-9:]+', splittedWord):
                idxOfZeroInSplittedLine = idxSplitted
            idxSplitted = idxSplitted+1

        # Analyze pattern
        self.patternId = self._analyzeChaptersPattern(
            splittedLineList, idxOfZeroInSplittedLine)
        logPrint.printLog("Pattern detected: "+str(self.patternId))

        idxMatrix = 0
        # To avoid false end-of-chapters due to problems of formatting in the description, another attempt is given to each non-match
        numberOfRemainingAttemptsToParseEachLine = self.MAX_ATTEMPTS_NB_TO_PARSE_TIME_AND_TITLE
        logPrint.printLog("While parsing the chapters, a maximum of "+str(
            self.MAX_ATTEMPTS_NB_TO_PARSE_TIME_AND_TITLE)+" not matching line(s) is accepted.")
        offsetForIdxMatrixBecauseOfFalseErrors = 0

        # Max length of the matrix
        while (idxMatrix < self.MAX_SIZE_OF_MATRIX):
            # Avoid overflow
            if((self.lineNbZeroZero + idxMatrix + offsetForIdxMatrixBecauseOfFalseErrors < len(self.descriptionLinesList)) and numberOfRemainingAttemptsToParseEachLine > 0):
                line = self.descriptionLinesList[self.lineNbZeroZero +
                                                 idxMatrix + offsetForIdxMatrixBecauseOfFalseErrors]
                if re.search('[0-9:]+:[0-9:]+', line):
                    # Reset for the next formatting error found
                    numberOfRemainingAttemptsToParseEachLine = self.MAX_ATTEMPTS_NB_TO_PARSE_TIME_AND_TITLE

                    # FIXME Does not work for "[2:20] the past inside the present"
                    splittedLine = re.split(r'([0-9:]+:[0-9:]+)', line)

                    # Too specific, commented and will be deleted after testing
                    # offsetForSplittedLineReading = 0
                    # if splittedLine[0] == "":
                    #     # re.split created an empty cell at the beginning, ignore it
                    #     offsetForSplittedLineReading = 1

                    # Pattern 0 could include the case where time is not the first word, the shift to do is idxOfZeroInSplittedLine
                    # We here take thy hypothesis that the shift of the 0:00 line is the same for every line
                    if self.patternId == 0:
                        time = splittedLine[0 + idxOfZeroInSplittedLine]
                        titleAndDelim = splittedLine[1 +
                                                     idxOfZeroInSplittedLine]
                    elif self.patternId == 1:
                        time = splittedLine[1]
                        titleAndDelim = splittedLine[0]
                    else:
                        logPrint.printError(
                            "Chapters pattern not found. Exiting.")
                        exit(-4)

                    logPrint.printLog("Matching line found, line "+str(self.lineNbZeroZero +
                                                                       idxMatrix + offsetForIdxMatrixBecauseOfFalseErrors)+", time "+time)
                    # The title is stripped to not store useless characters in the beginning and in the end
                    title = titleAndDelim.strip(" -_[]#:")

                    # Strip remaining parenthesis around timestamp e.g. "(25:32) title" without cutting the included parenthesis of one title
                    # e.g. "(25:32) title (featuring Pitbull)"
                    title = title.lstrip(") ")
                    title = title.rstrip("( ")

                    self.chaptersMatrix[idxMatrix, 0] = time
                    self.chaptersMatrix[idxMatrix, 1] = title

                    # Shift the index only if we have found something to avoid holes because of formatting errors
                    idxMatrix = idxMatrix+1
                else:
                    if numberOfRemainingAttemptsToParseEachLine > 0:
                        # Second chance
                        logPrint.printLog("Not matching line found, line "+str(self.lineNbZeroZero +
                                                                               idxMatrix + offsetForIdxMatrixBecauseOfFalseErrors)+", another chance is given.")
                        numberOfRemainingAttemptsToParseEachLine = numberOfRemainingAttemptsToParseEachLine - 1
                        offsetForIdxMatrixBecauseOfFalseErrors = offsetForIdxMatrixBecauseOfFalseErrors + 1
            else:
                # No more time is detected and the formatting error margin is consumed, the chapter list is over
                logPrint.printLog("No more matching line found, line "+str(self.lineNbZeroZero +
                                                                           idxMatrix + offsetForIdxMatrixBecauseOfFalseErrors)+", the chapter list parsing is over.")
                self.chaptersMatrixSize = idxMatrix
                # End the while loop
                idxMatrix = self.MAX_SIZE_OF_MATRIX

        logPrint.printDebug("chaptersMatrix, " +
                            str(self.chaptersMatrixSize)+" lines: ")
        for idxMatrix in range(self.chaptersMatrixSize):
            logPrint.printDebug("|" +
                                self.chaptersMatrix[idxMatrix, 0]+"|"+self.chaptersMatrix[idxMatrix, 1]+"|")
Ejemplo n.º 7
0
        )
    else:
        prefix = ""
        logPrint.printLog("No prefix read from the program's arguments.")

    # Instantiate musicDisplayer to launch a timer and print the correct music name
    musicDisplayerInst = musicDisplayer(outputFilePath, chaptersMatrix, prefix)

    # Launch the timer
    musicDisplayerInst.start()


if __name__ == "__main__":
    # Parsing config.ini
    internalConfigInst = internalConfig()

    logLevel = internalConfigInst.getVerbosityLevel()
    outputFilePath = internalConfigInst.getOutputFilePath()

    # Log level = debug
    logPrint(logLevel)

    logPrint.printDebug("Config.ini: logLevel=" + str(logLevel))
    logPrint.printDebug("Config.ini: outputFilePath=" + outputFilePath)

    if len(sys.argv) >= 2 and len(sys.argv) <= 3:
        main(outputFilePath, sys.argv[1:])
    else:
        logPrint.printError("Usage: timeSnip.py <YoutubeURL> [prefix]")
        exit(-1)