def setline(self, line: Union[SimpleLine, str, Evento], pos: int) -> 'Events': """ Replace a line in position 'pos'. :param line: SimpleLine, String or Evento. Line to set. :param pos: Integer. Index position to set. :return: self. """ if True not in {isinstance(line, _) for _ in [str, SimpleLine, Evento]}: raise TypeError(f"{line} has to be string, SimpleLine or Evento.") if isinstance(pos, int) is False: raise TypeError(f"{pos} has to be an Integer.") lista = self.getlineall() if len(lista) < pos: raise ValueError(f"There is no line in position {pos}.") if isinstance(line, Evento): if self.__formato is not None: __value = Evento(line) __value.setformato(self.__formato.getformat()) else: __value = SimpleLine(f"{line}") self.__lines[pos] = __value return self __value = SimpleLine(line) if self.__formato is not None: # __checkline: Set it as event if valid, else set as SimpleLine self.__lines[pos] = self.__checkline(__value) else: self.__lines[pos] = __value return self
def readline(self, linha: Union[SimpleLine, str]) -> 'ScriptInfo': """ Read the values from the text line loaded from the [Script Info] section of the loaded file. :param linha: String or SimpleLine object to be read. :return: self. """ if (isinstance(linha, SimpleLine) or isinstance(linha, str)) is False: raise TypeError(f"{linha} has to be SimpleLine or String.") newlinha = SimpleLine(linha) if(f"{linha}".strip()).lower() == "[Script Info]".lower(): pass elif newlinha.gettipo() is None: # (Linha.gettipo() is None) means that line is to be treated as comment. pass else: for _ in range(len(self.linelist)): if isinstance(self.linelist[_], SimpleLine): if ((self.linelist[_].gettipo()).strip()).lower() == ((newlinha.gettipo()).strip()).lower(): self.linelist[_] = newlinha break else: self.linelist.append(newlinha) return self
def readline(self, arg: Union[str, SimpleLine]) -> 'Events': """ Read a line and append a "SimpleLine" or an Evento to the list. If format is not set, only append "SimpleLine" instances. If it finds format, set format, then check previous lines for every valid Evento. If format is set, and line is a valid event, it will always append an "Evento" instance. :param arg: String or SimpleLine. :return: self. """ def comparing(arg1, arg2): if arg1 is None: if arg2 is None: return True return False if arg2 is None: return False if (isinstance(arg1, str) or isinstance(arg2, str)) is False: raise TypeError(f"{arg} must be a String") return ((arg1.strip()).lower()).startswith(arg2.lower()) if (isinstance(arg, str) or isinstance(arg, SimpleLine)) is False: raise TypeError(f"{arg} must be a SimpleLine or String.") __value = SimpleLine(arg) if self.getformat() is None: # If it starts with: if comparing(__value.gettipo(), "format"): self.setformat(__value) # print(f"{type(self.getformat())}{self.getformat()}") replacement = [] for _ in self.__lines: # Will become Evento if valid. __x__ = self.__checkline(_) if isinstance(__x__, Evento): # Replace all SimpleLine with Evento replacement.append(__x__) # check if it starts with any of the valid event types if True in {comparing(__value.gettipo(), _) for _ in self.getalleventtypes()}: if self.getformat() is not None: __x__ = self.__checkline(__value) # print(f"__x__ = {__x__} __value = {__value}") # print(f"__x__ = {__x__} __value = {type(__value)}") # print(f"__x__ = {__x__} type = {type(__x__)}") if isinstance(__x__, Evento): self.__lines.append(self.__checkline(__value)) else: self.__lines.append(__value) return self
def __init__(self) -> None: self.scriptinfo = ScriptInfo() self.v4styles = V4Styles() self.events = Events() self.__defaulttitles__ = [ f"{_}" for _ in SimpleLine().__defaulttitles__ ] self.__lowertitles__ = [f"{_}" for _ in SimpleLine().__lowertitles__] self.__readers__ = (self.scriptinfo.readline, self.v4styles.readline, self.events.readline) self.__readerpos__ = None
def readline(self, line: Union[str, SimpleLine]) -> 'Formato': """ :param line: :return: """ if (isinstance(line, str) or isinstance(line, SimpleLine)) is False: raise TypeError(f"Expected a String or 'SimpleLine instance. Got {line} of type {type(line)} instead.") newline = SimpleLine(line) if (newline.gettipo().strip()).lower() == "format": newcols = [_.strip() for _ in newline.gettexto().split(",")] return self
def getline(self, pos: int, copyreference: bool = True) -> Union["Estilo", SimpleLine, None]: """ Retrieve a reference for a line from this instance's style list. If invalid lines are enabled ('storeall'), they can be disabled completely by calling the method 'clearinvalidlines' :param pos: index to retrieve. :param copyreference: if set to True. Returns a reference of the object, instead of a copy. :return: Estilo instance mostly. If storeall = True, may also include invalid SimpleLine instances. None if index is invalid. """ if isinstance(pos, int) is False: raise TypeError(f"Argument 'pos' has to be int. Currently it is {pos} of type {type(pos)}") if (pos < 0) or (pos >= len(self.lines)): return None if (isinstance(self.lines[pos], Estilo) or isinstance(self.lines[pos], SimpleLine)) is False: raise TypeError(f"Value found wasn't Estilo or SimpleLine somehow. Value in {pos} is {self.lines[pos]} of " + f"type {type(self.lines[pos])}") if copyreference is False: if isinstance(self.lines[pos], SimpleLine): return SimpleLine(self.lines[pos]) elif isinstance(self.lines[pos], Estilo): return Estilo(self.lines[pos]) return self.lines[pos]
def loadfile(self, arg: str) -> 'SubPackage': """ Load an SSA text file into this object. :param arg: String. Local Address of file. :return: self. """ if isinstance(arg, str) is False: raise TypeError(f"{arg} must be a file address (String).") try: with open(arg, "r") as f: for _ in f: __line = SimpleLine(_) __linelower = f"{__line}".lower() __checking__ = [ __ in __linelower for __ in self.__lowertitles__ ] if True in __checking__: self.__readerpos__ = __checking__.index(True) else: if self.__readerpos__ is not None: # Call the reading function for the current section (self.__readers__[self.__readerpos__])(__line) except FileNotFoundError: raise ValueError(f"{arg} file could not be found.") return self
def getvaluelist(self) -> List[SimpleLine]: """ Return a SimpleLine list with all stored values. :return: list with 'Dados.SimpleLine' elements. """ listaderetorno = [] for _ in self.linelist: if isinstance(_, SimpleLine): listaderetorno.append(SimpleLine(_)) return listaderetorno
def __checkline(self, argline: SimpleLine) -> Union[Evento, SimpleLine]: """ Checks if argline is a valid event. Returns it as Evento if true. Otherwise, return the same object. if format is not set, raise an assert error. :param argline: SimpleLine instance. :return: SimpleLine instance or Evento instance. """ assert self.__formato is not None, f"Formato is not set." if isinstance(argline, SimpleLine) is False: raise TypeError(f"{argline} has to be a SimpleLine.") if argline.gettipo() is None: return argline # if the text before the first ":" is an event type if ((argline.gettipo()).strip()).lower() in self.getalleventtypes(): # Create an event, set format, then set event type and values with readevent return (Evento().setformato(self.__formato.getformat())).readevent(argline) # Just store it as SimpleLine. Treating it as a comment return argline
def setformato(self, args: List[str]) -> 'Evento': """ Sets formato to the list of strings. :param args: list of 10 strings. Each String must be in 'self.gettiposdisponiveis()'. :return: self. """ __value = args if isinstance(args, str) or isinstance(args, SimpleLine): __value = [ _.strip() for _ in (( SimpleLine(f"{__value}").gettexto()).strip()).split(",") ] if len(__value) != 10: raise ValueError(f"{__value} must have 10 columns") for _ in __value: if _.lower() not in [ __.lower() for __ in self.tiposdisponiveis ]: raise ValueError(f"{_}: Invalid format type.") if isinstance(__value, list) is False: raise TypeError(f"{args} must be a list of Strings") if len(__value) != 10: raise ValueError( f"{__value} must have 10 elements ({len(__value)})") for _ in __value: if isinstance(_, str) is False: raise ValueError(f"{__value} all elements must be Strings") # creating trimmed and lowered version of the string using list comprehension __values = [(_.strip()).lower() for _ in __value] for _ in range(10): if __values[_] not in self.tiposdisponiveis: raise ValueError( f"{__value[_]} -> {__values[_]} not in {self.tiposdisponiveis}" ) # assert __values[_] in self.tiposdisponiveis, f"{args[_]} -> {__values[_]} not in {self.tiposdisponiveis}" # checking duplicates very inneficiently, since each combination will be checked twice # easier to read though for _ in range(10): for __ in range(10): if _ != __: if __values[_] == __values[__]: raise ValueError( f"{__values} -> duplicates found in index {_} and {__}" ) # setting the list using list comprehension self.formato = [f"{_}" for _ in __values] return self
def readevent(self, arg: Union[str, SimpleLine]) -> 'Evento': """ Read an event line and stores it's columns. :param arg: String or SimpleLine instance. :return: self. """ assert self.getformato() is not None, f"Format is not set" if (isinstance(arg, str) or isinstance(arg, SimpleLine)) is False: raise TypeError( f"{arg} must be a string or a 'SimpleLine' instance") # If it's a string, splits type from the text. If it's a SimpleLine, remains the same. __event = SimpleLine(arg) if __event.gettipo() is None: raise ValueError("Invalid Event") # This will raise ValueError if it is invalid self.seteventtype(__event.gettipo()) __values = [_.strip() for _ in __event.gettexto().split(",", 9)] if len(__values) != 10: raise ValueError( f"{len(__values)}: number of columns has to be 10.") return self.setvalues(__values)
def getlineall(self) -> List[Union[SimpleLine, Evento]]: """ Return all lines, "SimpleLine" instances and "Evento"s :return: list with "SimpleLine" instances and "Evento" instances. """ if len(self.__lines) == 0: return [] saida = [] for _ in self.__lines: # If formato is None, it will never try to copy an Evento instance to the output if isinstance(_, SimpleLine) or isinstance(_, str) or (self.__formato is None): saida.append(SimpleLine(_)) else: saida.append(Evento(_)) return saida
def getlines(self, copyreference: bool = True) -> List[Union['Estilo', SimpleLine]]: """ Returns a reference to this instance's list. If invalid lines are enabled ('storeall'), they can be disabled completely by calling the method 'clearinvalidlines' :param copyreference: if set to True, returns a reference to the object. Else returns a copy of the object. :return reference to a list of Estilo and SimpleLine instances. """ __ = [] if not copyreference: for _ in self.lines: if isinstance(_, SimpleLine): __.append(SimpleLine(_)) if isinstance(_, Estilo): __.append(Estilo(_)) return __ return self.lines
def readline(self, argline): """ Store argline as Estilo if it is valid. SimpleLine if it isn't :param argline: String or SimpleLine instance. :return: self.""" if (isinstance(argline, str) or isinstance(argline, SimpleLine)) is False: raise TypeError( f"{argline} must be a string or SimpleLine instance.") # f"{}" will turn the SimpleLine into a String # Until format is read, everything will be stored as SimpleLine instances # When format is read, replace the list with only valid events novov4style = SimpleLine(argline) if len(self.Format.getformat()) == 0: if (( (novov4style.gettipo()).strip()).lower()).startswith("format"): self.readformat(f"{novov4style}") replacement = [] for _ in self.V4Style: if isinstance(_, Estilo): replacement.append(_) elif isinstance(_, SimpleLine): if ((_.gettipo()).lower()).startswith("style"): replacement.append(Estilo(self.getformat(), f"{_}")) self.V4Style = replacement else: self.V4Style.append(novov4style) else: if novov4style.gettipo() is not None: if (((novov4style.gettipo()).strip()).lower() ).startswith("style"): novov4style = Estilo(self.getformat(), f"{argline}") self.V4Style.append(novov4style) return self
def readline(self, line: Union[str, SimpleLine]) -> 'V4Styles': """ Read the line given, store the value then return itself. Method is not case-sensitive. :param line: String or SimpleLine. Only lines that start with 'format:' or 'style:' are considered valid. :returns: self """ if (isinstance(line, str) or isinstance(line, SimpleLine) or line is not None) is False: raise TypeError(f"{line} type ({type(line)}) is not compatible with V4Styles") newline = SimpleLine(line) # if line read isn't in the format '{type}: {text}' if newline.gettipo() is None: # It will store if set beforehand if self.storeall: self.lines.append(newline) return self # if line read starts with 'Format:' if (newline.gettipo().strip()).lower() == "format": # self.lines.append(Formato(newline)) newline = Formato(newline) self.formatline = newline # run through all the Estilos previously read and tell them what is this file's format self.lines = [_.setformato(newline) if isinstance(_, Estilo) else _ for _ in self.lines] return self # if line starts with 'Style:' if (newline.gettipo().strip()).lower() == "style": if self.formatline is not None: self.lines.append(Estilo(newline, self.formatline)) else: self.lines.append(Estilo(newline)) return self # Won't do anything if it is a line in the format '{type}:{text}' if type is not format or style # self.lines.append(newline) return self