def import_sqlite_db(self): """ Import the songs from an EasyWorship 6 SQLite database """ songs_db_path = next(self.import_source.rglob('Songs.db'), None) song_words_db_path = next(self.import_source.rglob('SongWords.db'), None) invalid_dir_msg = translate('SongsPlugin.EasyWorshipSongImport', 'This does not appear to be a valid Easy Worship 6 database directory.') invalid_db_msg = translate('SongsPlugin.EasyWorshipSongImport', 'This is not a valid Easy Worship 6 database.') # check to see if needed files are there if not (songs_db_path and songs_db_path.is_file()): self.log_error(self.import_source, invalid_dir_msg) return if not (song_words_db_path and song_words_db_path.is_file()): self.log_error(self.import_source, invalid_dir_msg) return # get database handles songs_conn = sqlite3.connect(str(songs_db_path)) words_conn = sqlite3.connect(str(song_words_db_path)) if songs_conn is None or words_conn is None: self.log_error(self.import_source, invalid_db_msg) songs_conn.close() words_conn.close() return songs_db = songs_conn.cursor() words_db = words_conn.cursor() if songs_conn is None or words_conn is None: self.log_error(self.import_source, invalid_db_msg) songs_conn.close() words_conn.close() return # Take a stab at how text is encoded self.encoding = 'cp1252' self.encoding = retrieve_windows_encoding(self.encoding) if not self.encoding: log.debug('No encoding set.') return # import songs songs = songs_db.execute('SELECT rowid,title,author,copyright,vendor_id FROM song;') for song in songs: song_id = song[0] # keep extra copy of title for error message because error check clears it self.title = title = song[1] self.author = song[2] self.copyright = song[3] self.ccli_number = song[4] words = words_db.execute('SELECT words FROM word WHERE song_id = ?;', (song_id,)) self.set_song_import_object(self.author, words.fetchone()[0].encode()) if not self.finish(): self.log_error(self.import_source, translate('SongsPlugin.EasyWorshipSongImport', '"{title}" could not be imported. {entry}'). format(title=title, entry=self.entry_error_log)) # close database handles songs_conn.close() words_conn.close() return
def getEncoding(self): """ Detect character encoding of an openlp.org 1.x song database. """ # Connect to the database. connection = sqlite.connect(self.importSource.encode( sys.getfilesystemencoding()), mode=0444) cursor = connection.cursor() detector = UniversalDetector() # Detect charset by authors. cursor.execute(u'SELECT authorname FROM authors') authors = cursor.fetchall() for author in authors: detector.feed(author[0]) if detector.done: detector.close() return detector.result[u'encoding'] # Detect charset by songs. cursor.execute(u'SELECT songtitle, copyrightinfo, ' u'lyrics || \'\' AS lyrics FROM songs') songs = cursor.fetchall() for index in [0, 1, 2]: for song in songs: detector.feed(song[index]) if detector.done: detector.close() return detector.result[u'encoding'] # Detect charset by songs. cursor.execute(u'SELECT name FROM sqlite_master ' u'WHERE type = \'table\' AND name = \'tracks\'') if cursor.fetchall(): cursor.execute(u'SELECT fulltrackname FROM tracks') tracks = cursor.fetchall() for track in tracks: detector.feed(track[0]) if detector.done: detector.close() return detector.result[u'encoding'] detector.close() return retrieve_windows_encoding(detector.result[u'encoding'])
def decode(self, data): try: # Don't question this, it works... return data.decode('utf-8').encode('cp1251').decode('cp1251') except: return data.decode(retrieve_windows_encoding())
def import_ews(self): """ Import the songs from service file The full spec of the ews files can be found here: https://github.com/meinders/lithium-ews/blob/master/docs/ews%20file%20format.md or here: http://wiki.openlp.org/Development:EasyWorship_EWS_Format """ # Open ews file if it exists if not os.path.isfile(self.import_source): log.debug('Given ews file does not exists.') return # Make sure there is room for at least a header and one entry if os.path.getsize(self.import_source) < 892: log.debug('Given ews file is to small to contain valid data.') return # Take a stab at how text is encoded self.encoding = 'cp1252' self.encoding = retrieve_windows_encoding(self.encoding) if not self.encoding: log.debug('No encoding set.') return self.ews_file = open(self.import_source, 'rb') # EWS header, version '1.6'/' 3'/' 5': # Offset Field Data type Length Details # -------------------------------------------------------------------------------------------------- # 0 Filetype string 38 Specifies the file type and version. # "EasyWorship Schedule File Version 1.6" or # "EasyWorship Schedule File Version 3" or # "EasyWorship Schedule File Version 5" # 40/48/56 Entry count int32le 4 Number of items in the schedule # 44/52/60 Entry length int16le 2 Length of schedule entries: 0x0718 = 1816 # Get file version type, = struct.unpack('<38s', self.ews_file.read(38)) version = type.decode()[-3:] # Set fileposition based on filetype/version file_pos = 0 if version == ' 5': file_pos = 56 elif version == ' 3': file_pos = 48 elif version == '1.6': file_pos = 40 else: log.debug('Given ews file is of unknown version.') return entry_count = self.get_i32(file_pos) entry_length = self.get_i16(file_pos + 4) file_pos += 6 self.import_wizard.progress_bar.setMaximum(entry_count) # Loop over songs for i in range(entry_count): # Load EWS entry metadata: # Offset Field Data type Length Details # ------------------------------------------------------------------------------------------------ # 0 Title cstring 50 # 307 Author cstring 50 # 358 Copyright cstring 100 # 459 Administrator cstring 50 # 800 Content pointer int32le 4 Position of the content for this entry. # 820 Content type int32le 4 0x01 = Song, 0x02 = Scripture, 0x03 = Presentation, # 0x04 = Video, 0x05 = Live video, 0x07 = Image, # 0x08 = Audio, 0x09 = Web # 1410 Song number cstring 10 self.set_defaults() self.title = self.get_string(file_pos + 0, 50) authors = self.get_string(file_pos + 307, 50) copyright = self.get_string(file_pos + 358, 100) admin = self.get_string(file_pos + 459, 50) cont_ptr = self.get_i32(file_pos + 800) cont_type = self.get_i32(file_pos + 820) self.ccli_number = self.get_string(file_pos + 1410, 10) # Only handle content type 1 (songs) if cont_type != 1: file_pos += entry_length continue # Load song content # Offset Field Data type Length Details # ------------------------------------------------------------------------------------------------ # 0 Length int32le 4 Length (L) of content, including the compressed content # and the following fields (14 bytes total). # 4 Content string L-14 Content compressed with deflate. # Checksum int32be 4 Alder-32 checksum. # (unknown) 4 0x51 0x4b 0x03 0x04 # Content length int32le 4 Length of content after decompression content_length = self.get_i32(cont_ptr) deflated_content = self.get_bytes(cont_ptr + 4, content_length - 10) deflated_length = self.get_i32(cont_ptr + 4 + content_length - 6) inflated_content = zlib.decompress(deflated_content, 15, deflated_length) if copyright: self.copyright = copyright if admin: if copyright: self.copyright += ', ' self.copyright += translate('SongsPlugin.EasyWorshipSongImport', 'Administered by {admin}').format(admin=admin) # Set the SongImport object members. self.set_song_import_object(authors, inflated_content) if self.stop_import_flag: break if self.entry_error_log: self.log_error(self.import_source, translate('SongsPlugin.EasyWorshipSongImport', '"{title}" could not be imported. {entry}').format(title=self.title, entry=self.entry_error_log)) self.entry_error_log = '' elif not self.finish(): self.log_error(self.import_source) # Set file_pos for next entry file_pos += entry_length self.ews_file.close()
def import_db(self): """ Import the songs from the database """ # Open the DB and MB files if they exist import_source_mb = self.import_source.replace('.DB', '.MB').replace('.db', '.mb') if not os.path.isfile(self.import_source): self.log_error(self.import_source, translate('SongsPlugin.EasyWorshipSongImport', 'This file does not exist.')) return if not os.path.isfile(import_source_mb): self.log_error(self.import_source, translate('SongsPlugin.EasyWorshipSongImport', 'Could not find the "Songs.MB" file. It must be in the same ' 'folder as the "Songs.DB" file.')) return db_size = os.path.getsize(self.import_source) if db_size < 0x800: self.log_error(self.import_source, translate('SongsPlugin.EasyWorshipSongImport', 'This file is not a valid EasyWorship database.')) return db_file = open(self.import_source, 'rb') self.memo_file = open(import_source_mb, 'rb') # Don't accept files that are clearly not paradox files record_size, header_size, block_size, first_block, num_fields = struct.unpack('<hhxb8xh17xh', db_file.read(35)) if header_size != 0x800 or block_size < 1 or block_size > 4: db_file.close() self.memo_file.close() self.log_error(self.import_source, translate('SongsPlugin.EasyWorshipSongImport', 'This file is not a valid EasyWorship database.')) return # Take a stab at how text is encoded self.encoding = 'cp1252' db_file.seek(106) code_page, = struct.unpack('<h', db_file.read(2)) if code_page == 852: self.encoding = 'cp1250' # The following codepage to actual encoding mappings have not been # observed, but merely guessed. Actual example files are needed. elif code_page == 737: self.encoding = 'cp1253' elif code_page == 775: self.encoding = 'cp1257' elif code_page == 855: self.encoding = 'cp1251' elif code_page == 857: self.encoding = 'cp1254' elif code_page == 866: self.encoding = 'cp1251' elif code_page == 869: self.encoding = 'cp1253' elif code_page == 862: self.encoding = 'cp1255' elif code_page == 874: self.encoding = 'cp874' self.encoding = retrieve_windows_encoding(self.encoding) if not self.encoding: self.log_error(self.import_source, translate('SongsPlugin.EasyWorshipSongImport', 'Could not retrieve encoding.')) return # Read the field description information db_file.seek(120) field_info = db_file.read(num_fields * 2) db_file.seek(4 + (num_fields * 4) + 261, os.SEEK_CUR) field_names = db_file.read(header_size - db_file.tell()).split(b'\0', num_fields) field_names.pop() field_descriptions = [] for i, field_name in enumerate(field_names): field_type, field_size = struct.unpack_from('BB', field_info, i * 2) field_descriptions.append(FieldDescEntry(field_name, field_type, field_size)) self.set_record_struct(field_descriptions) # Pick out the field description indexes we will need try: success = True fi_title = self.find_field(b'Title') fi_author = self.find_field(b'Author') fi_copy = self.find_field(b'Copyright') fi_admin = self.find_field(b'Administrator') fi_words = self.find_field(b'Words') fi_ccli = self.find_field(b'Song Number') except IndexError: # This is the wrong table success = False # There does not appear to be a _reliable_ way of getting the number of songs/records, so loop through the file # blocks and total the number of records. Store the information in a list so we dont have to do all this again. cur_block = first_block total_count = 0 block_list = [] while cur_block != 0 and success: cur_block_pos = header_size + ((cur_block - 1) * 1024 * block_size) db_file.seek(cur_block_pos) cur_block, rec_count = struct.unpack('<h2xh', db_file.read(6)) rec_count = (rec_count + record_size) // record_size block_list.append((cur_block_pos, rec_count)) total_count += rec_count self.import_wizard.progress_bar.setMaximum(total_count) for block in block_list: cur_block_pos, rec_count = block db_file.seek(cur_block_pos + 6) # Loop through each record within the current block for i in range(rec_count): if self.stop_import_flag: break try: raw_record = db_file.read(record_size) self.fields = self.record_structure.unpack(raw_record) self.set_defaults() self.title = self.get_field(fi_title).decode(self.encoding) # Get remaining fields. copy = self.get_field(fi_copy) admin = self.get_field(fi_admin) ccli = self.get_field(fi_ccli) authors = self.get_field(fi_author) words = self.get_field(fi_words) if copy: self.copyright = copy.decode(self.encoding) if admin: if copy: self.copyright += ', ' self.copyright += translate('SongsPlugin.EasyWorshipSongImport', 'Administered by {admin}').format(admin=admin.decode(self.encoding)) if ccli: self.ccli_number = ccli.decode(self.encoding) if authors: authors = authors.decode(self.encoding) else: authors = '' # Set the SongImport object members. self.set_song_import_object(authors, words) if self.stop_import_flag: break if self.entry_error_log: self.log_error(self.import_source, translate('SongsPlugin.EasyWorshipSongImport', '"{title}" could not be imported. ' '{entry}').format(title=self.title, entry=self.entry_error_log)) self.entry_error_log = '' elif not self.finish(): self.log_error(self.import_source) except Exception as e: self.log_error(self.import_source, translate('SongsPlugin.EasyWorshipSongImport', '"{title}" could not be imported. {error}').format(title=self.title, error=e)) db_file.close() self.memo_file.close()
def import_ews(self): """ Import the songs from service file The full spec of the ews files can be found here: https://github.com/meinders/lithium-ews/blob/master/docs/ews%20file%20format.md or here: http://wiki.openlp.org/Development:EasyWorship_EWS_Format """ # Open ews file if it exists if not os.path.isfile(self.import_source): log.debug('Given ews file does not exists.') return # Make sure there is room for at least a header and one entry if os.path.getsize(self.import_source) < 892: log.debug('Given ews file is to small to contain valid data.') return # Take a stab at how text is encoded self.encoding = 'cp1252' self.encoding = retrieve_windows_encoding(self.encoding) if not self.encoding: log.debug('No encoding set.') return self.ews_file = open(self.import_source, 'rb') # EWS header, version '1.6'/' 3'/' 5': # Offset Field Data type Length Details # -------------------------------------------------------------------------------------------------- # 0 Filetype string 38 Specifies the file type and version. # "EasyWorship Schedule File Version 1.6" or # "EasyWorship Schedule File Version 3" or # "EasyWorship Schedule File Version 5" # 40/48/56 Entry count int32le 4 Number of items in the schedule # 44/52/60 Entry length int16le 2 Length of schedule entries: 0x0718 = 1816 # Get file version type, = struct.unpack('<38s', self.ews_file.read(38)) version = type.decode()[-3:] # Set fileposition based on filetype/version file_pos = 0 if version == ' 5': file_pos = 56 elif version == ' 3': file_pos = 48 elif version == '1.6': file_pos = 40 else: log.debug('Given ews file is of unknown version.') return entry_count = self.get_i32(file_pos) entry_length = self.get_i16(file_pos + 4) file_pos += 6 self.import_wizard.progress_bar.setMaximum(entry_count) # Loop over songs for i in range(entry_count): # Load EWS entry metadata: # Offset Field Data type Length Details # ------------------------------------------------------------------------------------------------ # 0 Title cstring 50 # 307 Author cstring 50 # 358 Copyright cstring 100 # 459 Administrator cstring 50 # 800 Content pointer int32le 4 Position of the content for this entry. # 820 Content type int32le 4 0x01 = Song, 0x02 = Scripture, 0x03 = Presentation, # 0x04 = Video, 0x05 = Live video, 0x07 = Image, # 0x08 = Audio, 0x09 = Web # 1410 Song number cstring 10 self.set_defaults() self.title = self.get_string(file_pos + 0, 50) authors = self.get_string(file_pos + 307, 50) copyright = self.get_string(file_pos + 358, 100) admin = self.get_string(file_pos + 459, 50) cont_ptr = self.get_i32(file_pos + 800) cont_type = self.get_i32(file_pos + 820) self.ccli_number = self.get_string(file_pos + 1410, 10) # Only handle content type 1 (songs) if cont_type != 1: file_pos += entry_length continue # Load song content # Offset Field Data type Length Details # ------------------------------------------------------------------------------------------------ # 0 Length int32le 4 Length (L) of content, including the compressed content # and the following fields (14 bytes total). # 4 Content string L-14 Content compressed with deflate. # Checksum int32be 4 Alder-32 checksum. # (unknown) 4 0x51 0x4b 0x03 0x04 # Content length int32le 4 Length of content after decompression content_length = self.get_i32(cont_ptr) deflated_content = self.get_bytes(cont_ptr + 4, content_length - 10) deflated_length = self.get_i32(cont_ptr + 4 + content_length - 6) inflated_content = zlib.decompress(deflated_content, 15, deflated_length) if copyright: self.copyright = copyright if admin: if copyright: self.copyright += ', ' self.copyright += translate( 'SongsPlugin.EasyWorshipSongImport', 'Administered by %s') % admin # Set the SongImport object members. self.set_song_import_object(authors, inflated_content) if self.stop_import_flag: break if self.entry_error_log: self.log_error( self.import_source, translate('SongsPlugin.EasyWorshipSongImport', '"%s" could not be imported. %s') % (self.title, self.entry_error_log)) self.entry_error_log = '' elif not self.finish(): self.log_error(self.import_source) # Set file_pos for next entry file_pos += entry_length self.ews_file.close()
def import_db(self): """ Import the songs from the database """ # Open the DB and MB files if they exist import_source_mb = self.import_source.replace('.DB', '.MB').replace( '.db', '.mb') if not os.path.isfile(self.import_source): self.log_error( self.import_source, translate('SongsPlugin.EasyWorshipSongImport', 'This file does not exist.')) return if not os.path.isfile(import_source_mb): self.log_error( self.import_source, translate( 'SongsPlugin.EasyWorshipSongImport', 'Could not find the "Songs.MB" file. It must be in the same ' 'folder as the "Songs.DB" file.')) return db_size = os.path.getsize(self.import_source) if db_size < 0x800: self.log_error( self.import_source, translate('SongsPlugin.EasyWorshipSongImport', 'This file is not a valid EasyWorship database.')) return db_file = open(self.import_source, 'rb') self.memo_file = open(import_source_mb, 'rb') # Don't accept files that are clearly not paradox files record_size, header_size, block_size, first_block, num_fields = struct.unpack( '<hhxb8xh17xh', db_file.read(35)) if header_size != 0x800 or block_size < 1 or block_size > 4: db_file.close() self.memo_file.close() self.log_error( self.import_source, translate('SongsPlugin.EasyWorshipSongImport', 'This file is not a valid EasyWorship database.')) return # Take a stab at how text is encoded self.encoding = 'cp1252' db_file.seek(106) code_page, = struct.unpack('<h', db_file.read(2)) if code_page == 852: self.encoding = 'cp1250' # The following codepage to actual encoding mappings have not been # observed, but merely guessed. Actual example files are needed. elif code_page == 737: self.encoding = 'cp1253' elif code_page == 775: self.encoding = 'cp1257' elif code_page == 855: self.encoding = 'cp1251' elif code_page == 857: self.encoding = 'cp1254' elif code_page == 866: self.encoding = 'cp1251' elif code_page == 869: self.encoding = 'cp1253' elif code_page == 862: self.encoding = 'cp1255' elif code_page == 874: self.encoding = 'cp874' self.encoding = retrieve_windows_encoding(self.encoding) if not self.encoding: self.log_error( self.import_source, translate('SongsPlugin.EasyWorshipSongImport', 'Could not retrieve encoding.')) return # Read the field description information db_file.seek(120) field_info = db_file.read(num_fields * 2) db_file.seek(4 + (num_fields * 4) + 261, os.SEEK_CUR) field_names = db_file.read(header_size - db_file.tell()).split( b'\0', num_fields) field_names.pop() field_descriptions = [] for i, field_name in enumerate(field_names): field_type, field_size = struct.unpack_from( 'BB', field_info, i * 2) field_descriptions.append( FieldDescEntry(field_name, field_type, field_size)) self.set_record_struct(field_descriptions) # Pick out the field description indexes we will need try: success = True fi_title = self.find_field(b'Title') fi_author = self.find_field(b'Author') fi_copy = self.find_field(b'Copyright') fi_admin = self.find_field(b'Administrator') fi_words = self.find_field(b'Words') fi_ccli = self.find_field(b'Song Number') except IndexError: # This is the wrong table success = False # There does not appear to be a _reliable_ way of getting the number of songs/records, so loop through the file # blocks and total the number of records. Store the information in a list so we dont have to do all this again. cur_block = first_block total_count = 0 block_list = [] while cur_block != 0 and success: cur_block_pos = header_size + ((cur_block - 1) * 1024 * block_size) db_file.seek(cur_block_pos) cur_block, rec_count = struct.unpack('<h2xh', db_file.read(6)) rec_count = (rec_count + record_size) // record_size block_list.append((cur_block_pos, rec_count)) total_count += rec_count self.import_wizard.progress_bar.setMaximum(total_count) for block in block_list: cur_block_pos, rec_count = block db_file.seek(cur_block_pos + 6) # Loop through each record within the current block for i in range(rec_count): if self.stop_import_flag: break raw_record = db_file.read(record_size) self.fields = self.record_structure.unpack(raw_record) self.set_defaults() self.title = self.get_field(fi_title).decode('unicode-escape') # Get remaining fields. copy = self.get_field(fi_copy) admin = self.get_field(fi_admin) ccli = self.get_field(fi_ccli) authors = self.get_field(fi_author) words = self.get_field(fi_words) if copy: self.copyright = copy.decode('unicode-escape') if admin: if copy: self.copyright += ', ' self.copyright += translate( 'SongsPlugin.EasyWorshipSongImport', 'Administered by %s') % admin.decode('unicode-escape') if ccli: self.ccli_number = ccli.decode('unicode-escape') if authors: authors = authors.decode('unicode-escape') else: authors = '' # Set the SongImport object members. self.set_song_import_object(authors, words) if self.stop_import_flag: break if self.entry_error_log: self.log_error( self.import_source, translate('SongsPlugin.EasyWorshipSongImport', '"%s" could not be imported. %s') % (self.title, self.entry_error_log)) self.entry_error_log = '' elif not self.finish(): self.log_error(self.import_source) db_file.close() self.memo_file.close()
def doImport(self): # Open the DB and MB files if they exist import_source_mb = self.import_source.replace('.DB', '.MB') if not os.path.isfile(self.import_source) or not os.path.isfile(import_source_mb): return db_size = os.path.getsize(self.import_source) if db_size < 0x800: return db_file = open(self.import_source, 'rb') self.memoFile = open(import_source_mb, 'rb') # Don't accept files that are clearly not paradox files record_size, header_size, block_size, first_block, num_fields = struct.unpack('<hhxb8xh17xh', db_file.read(35)) if header_size != 0x800 or block_size < 1 or block_size > 4: db_file.close() self.memoFile.close() return # Take a stab at how text is encoded self.encoding = 'cp1252' db_file.seek(106) code_page, = struct.unpack('<h', db_file.read(2)) if code_page == 852: self.encoding = 'cp1250' # The following codepage to actual encoding mappings have not been # observed, but merely guessed. Actual example files are needed. elif code_page == 737: self.encoding = 'cp1253' elif code_page == 775: self.encoding = 'cp1257' elif code_page == 855: self.encoding = 'cp1251' elif code_page == 857: self.encoding = 'cp1254' elif code_page == 866: self.encoding = 'cp1251' elif code_page == 869: self.encoding = 'cp1253' elif code_page == 862: self.encoding = 'cp1255' elif code_page == 874: self.encoding = 'cp874' self.encoding = retrieve_windows_encoding(self.encoding) if not self.encoding: return # Read the field description information db_file.seek(120) field_info = db_file.read(num_fields * 2) db_file.seek(4 + (num_fields * 4) + 261, os.SEEK_CUR) field_names = db_file.read(header_size - db_file.tell()).split('\0', num_fields) field_names.pop() field_descs = [] for i, field_name in enumerate(field_names): field_type, field_size = struct.unpack_from('BB', field_info, i * 2) field_descs.append(FieldDescEntry(field_name, field_type, field_size)) self.setRecordStruct(field_descs) # Pick out the field description indexes we will need try: success = True fi_title = self.findField('Title') fi_author = self.findField('Author') fi_copy = self.findField('Copyright') fi_admin = self.findField('Administrator') fi_words = self.findField('Words') fi_ccli = self.findField('Song Number') except IndexError: # This is the wrong table success = False # There does not appear to be a _reliable_ way of getting the number of songs/records, so loop through the file # blocks and total the number of records. Store the information in a list so we dont have to do all this again. cur_block = first_block total_count = 0 block_list = [] while cur_block != 0 and success: cur_block_pos = header_size + ((cur_block - 1) * 1024 * block_size) db_file.seek(cur_block_pos) cur_block, rec_count = struct.unpack('<h2xh', db_file.read(6)) rec_count = (rec_count + record_size) / record_size block_list.append((cur_block_pos, rec_count)) total_count += rec_count self.import_wizard.progress_bar.setMaximum(total_count) for block in block_list: cur_block_pos, rec_count = block db_file.seek(cur_block_pos + 6) # Loop through each record within the current block for i in range(rec_count): if self.stop_import_flag: break raw_record = db_file.read(record_size) self.fields = self.recordStruct.unpack(raw_record) self.setDefaults() self.title = self.getField(fi_title) # Get remaining fields. copy = self.getField(fi_copy) admin = self.getField(fi_admin) ccli = self.getField(fi_ccli) authors = self.getField(fi_author) words = self.getField(fi_words) # Set the SongImport object members. if copy: self.copyright = copy if admin: if copy: self.copyright += ', ' self.copyright += translate('SongsPlugin.EasyWorshipSongImport', 'Administered by %s') % admin if ccli: self.ccliNumber = ccli if authors: # Split up the authors author_list = authors.split('/') if len(author_list) < 2: author_list = authors.split(';') if len(author_list) < 2: author_list = authors.split(',') for author_name in author_list: self.addAuthor(author_name.strip()) if words: # Format the lyrics result = strip_rtf(words, self.encoding) if result is None: return words, self.encoding = result verse_type = VerseType.tags[VerseType.Verse] for verse in SLIDE_BREAK_REGEX.split(words): verse = verse.strip() if not verse: continue verse_split = verse.split('\n', 1) first_line_is_tag = False # EW tags: verse, chorus, pre-chorus, bridge, tag, # intro, ending, slide for tag in VerseType.tags + ['tag', 'slide']: tag = tag.lower() ew_tag = verse_split[0].strip().lower() if ew_tag.startswith(tag): verse_type = tag[0] if tag == 'tag' or tag == 'slide': verse_type = VerseType.tags[VerseType.Other] first_line_is_tag = True number_found = False # check if tag is followed by number and/or note if len(ew_tag) > len(tag): match = NUMBER_REGEX.search(ew_tag) if match: number = match.group() verse_type += number number_found = True match = NOTE_REGEX.search(ew_tag) if match: self.comments += ew_tag + '\n' if not number_found: verse_type += '1' break self.addVerse(verse_split[-1].strip() if first_line_is_tag else verse, verse_type) if len(self.comments) > 5: self.comments += str(translate('SongsPlugin.EasyWorshipSongImport', '\n[above are Song Tags with notes imported from EasyWorship]')) if self.stop_import_flag: break if not self.finish(): self.logError(self.import_source) db_file.close() self.memoFile.close()
def decode(self, data): try: return str(data, chardet.detect(data)['encoding']) except: return str(data, retrieve_windows_encoding())
def decode(self, blob): while True: try: return blob.decode(self.encoding) except Exception as e: self.encoding = retrieve_windows_encoding()
def decode(self, blob): while True: try: return str(blob, self.encoding) except: self.encoding = retrieve_windows_encoding()