def xml_to_song(self, xml, parse_and_temporary_save=False): """ Create and save a song from OpenLyrics format xml to the database. Since we also export XML from external sources (e. g. OpenLyrics import), we cannot ensure, that it completely conforms to the OpenLyrics standard. ``xml`` The XML to parse (unicode). ``parse_and_temporary_save`` Switch to skip processing the whole song and storing the songs in the database with a temporary flag. Defaults to ``False``. """ # No xml get out of here. if not xml: return None if xml[:5] == u'<?xml': xml = xml[38:] song_xml = objectify.fromstring(xml) if hasattr(song_xml, u'properties'): properties = song_xml.properties else: return None # Formatting tags are new in OpenLyrics 0.8 if float(song_xml.get(u'version')) > 0.7: self._process_formatting_tags(song_xml, parse_and_temporary_save) song = Song() # Values will be set when cleaning the song. song.search_lyrics = u'' song.verse_order = u'' song.search_title = u'' song.temporary = parse_and_temporary_save self._process_copyright(properties, song) self._process_cclinumber(properties, song) self._process_titles(properties, song) # The verse order is processed with the lyrics! self._process_lyrics(properties, song_xml, song) self._process_comments(properties, song) self._process_authors(properties, song) self._process_songbooks(properties, song) self._process_topics(properties, song) clean_song(self.manager, song) self.manager.save_object(song) return song
def xml_to_song(self, xml, parse_and_temporary_save=False): """ Create and save a song from OpenLyrics format xml to the database. Since we also export XML from external sources (e. g. OpenLyrics import), we cannot ensure, that it completely conforms to the OpenLyrics standard. :param xml: The XML to parse (unicode). :param parse_and_temporary_save: Switch to skip processing the whole song and storing the songs in the database with a temporary flag. Defaults to ``False``. """ # No xml get out of here. if not xml: return None if xml[:5] == '<?xml': xml = xml[38:] song_xml = objectify.fromstring(xml) if hasattr(song_xml, 'properties'): properties = song_xml.properties else: return None # Formatting tags are new in OpenLyrics 0.8 if float(song_xml.get('version')) > 0.7: self._process_formatting_tags(song_xml, parse_and_temporary_save) song = Song() # Values will be set when cleaning the song. song.search_lyrics = '' song.verse_order = '' song.search_title = '' song.temporary = parse_and_temporary_save self._process_copyright(properties, song) self._process_cclinumber(properties, song) self._process_song_key(properties, song) self._process_transpose(properties, song) self._process_titles(properties, song) # The verse order is processed with the lyrics! self._process_lyrics(properties, song_xml, song) self._process_comments(properties, song) self._process_authors(properties, song) self._process_songbooks(properties, song) self._process_topics(properties, song) clean_song(self.manager, song) self.manager.save_object(song) return song
def finish(self, temporary_flag=False): """ All fields have been set to this song. Write the song to disk. :param temporary_flag: should this song be marked as temporary in the db (default=False) """ if not self.check_complete(): self.set_defaults() return False log.info( 'committing song {title} to database'.format(title=self.title)) song = Song() song.title = self.title if self.import_wizard is not None: self.import_wizard.increment_progress_bar( WizardStrings.ImportingType.format(source=song.title)) song.alternate_title = self.alternate_title # Values will be set when cleaning the song. song.search_title = '' song.search_lyrics = '' song.verse_order = '' song.song_number = self.song_number verses_changed_to_other = {} sxml = SongXML() other_count = 1 for (verse_def, verse_text, lang) in self.verses: if verse_def[0].lower() in VerseType.tags: verse_tag = verse_def[0].lower() else: new_verse_def = '{tag}{count:d}'.format( tag=VerseType.tags[VerseType.Other], count=other_count) verses_changed_to_other[verse_def] = new_verse_def other_count += 1 verse_tag = VerseType.tags[VerseType.Other] log.info('Versetype {old} changing to {new}'.format( old=verse_def, new=new_verse_def)) verse_def = new_verse_def sxml.add_verse_to_lyrics(verse_tag, verse_def[1:], normalize_str(verse_text), lang) song.lyrics = str(sxml.extract_xml(), 'utf-8') if not self.verse_order_list and self.verse_order_list_generated_useful: self.verse_order_list = self.verse_order_list_generated self.verse_order_list = [ verses_changed_to_other.get(v, v) for v in self.verse_order_list ] song.verse_order = ' '.join(self.verse_order_list) song.copyright = self.copyright song.comments = self.comments song.theme_name = self.theme_name song.ccli_number = self.ccli_number for author_text, author_type in self.authors: author = self.manager.get_object_filtered( Author, Author.display_name == author_text) if not author: author = Author.populate(display_name=author_text, last_name=author_text.split(' ')[-1], first_name=' '.join( author_text.split(' ')[:-1])) song.add_author(author, author_type) if self.song_book_name: song_book = self.manager.get_object_filtered( Book, Book.name == self.song_book_name) if song_book is None: song_book = Book.populate(name=self.song_book_name, publisher=self.song_book_pub) song.add_songbook_entry(song_book, song.song_number) for topic_text in self.topics: if not topic_text: continue topic = self.manager.get_object_filtered(Topic, Topic.name == topic_text) if topic is None: topic = Topic.populate(name=topic_text) song.topics.append(topic) song.temporary = temporary_flag # We need to save the song now, before adding the media files, so that # we know where to save the media files to. clean_song(self.manager, song) self.manager.save_object(song) # Now loop through the media files, copy them to the correct location, # and save the song again. for file_path, weight in self.media_files: media_file = self.manager.get_object_filtered( MediaFile, MediaFile.file_path == file_path) if not media_file: if file_path.parent: file_path = self.copy_media_file(song.id, file_path) song.media_files.append( MediaFile.populate(file_path=file_path, weight=weight)) self.manager.save_object(song) self.set_defaults() return song.id