def do_import(self): """ Receive a single file or a list of files to import. """ if isinstance(self.import_source, list): self.import_wizard.progress_bar.setMaximum(len(self.import_source)) for file_path in self.import_source: if self.stop_import_flag: return log.debug('Importing %s', file_path) try: self.set_defaults() # Get the song title self.title = file_path.stem with file_path.open('rb') as song_data: if not self.vaildate(file_path, song_data): continue seek_or_fail(song_data, 20) self.read_version = self.parse_version(song_data) # Seek to byte which stores number of blocks in the song seek_or_fail(song_data, 56) no_of_blocks = read_int(song_data, DataType.U8) # Seek to the beginning of the first block seek_or_fail(song_data, 82) for block_no in range(no_of_blocks): # Blocks are separated by 2 bytes, skip them, but not if this is the last block! if block_no != 0: seek_or_fail(song_data, 2, os.SEEK_CUR) text = self.parse_lines(song_data) block_type = BLOCK_TYPES[read_int( song_data, DataType.U32, 'little')] self.add_verse(text, block_type) # Now to extract the author self.parse_author(self.parse_string(song_data)) # Finally the copyright self.add_copyright(self.parse_string(song_data)) if not self.finish(): self.log_error(file_path) except IndexError: self.log_error(file_path, UiStrings().FileCorrupt) except Exception as e: self.log_error(file_path, e)
def parse_lines(self, song_data): lines = [] lines_to_read = read_int(song_data, DataType.U32, 'little') for line_no in range(0, lines_to_read): line_text = self.parse_string(song_data) if self.read_version >= (2, 1, 0): if read_or_fail(song_data, DataType.U8) == b'\x01': line_text = '{{minor}}{text}{{/minor}}'.format( text=line_text) lines.append(line_text) return '\n'.join(lines)
def test_read_int_u32_little(self): """ Test the :func:`read_int` function when reading an unsigned 32-bit int using 'little' endianness. """ # GIVEN: Some test data test_data = io.BytesIO(b'\x0f\xf0\x0f\xf0') # WHEN: Reading a an unsigned 32-bit int result = read_int(test_data, DataType.U32, 'little') # THEN: The an int should have been returned of the expected value assert result == 4027576335
def test_read_int_u16_big(self): """ Test the :func:`read_int` function when reading an unsigned 16-bit int using 'big' endianness. """ # GIVEN: Some test data test_data = io.BytesIO(b'\x0f\xf0\x0f\xf0') # WHEN: Reading a an unsigned 16-bit int result = read_int(test_data, DataType.U16, 'big') # THEN: The an int should have been returned of the expected value assert result == 4080
def parse_version(song_data): return (read_int(song_data, DataType.U32, 'little'), read_int(song_data, DataType.U32, 'little'), read_int(song_data, DataType.U32, 'little'))