def __init__(self, locale=None, music_key='C'): if isinstance(music_key, str): self.music_key = music_key else: self.music_key = Resources.DEFAULT_KEY print( "\n***ERROR: Invalid song key passed to Song(): using {self.music_key} instead" ) self.locale = locale self.lines = [] self.meta = { 'title': [ Lang.get_string("song_meta/title", self.locale) + ':', Lang.get_string("song_meta/untitled", self.locale) ], 'artist': [Lang.get_string("song_meta/artist", self.locale) + ': ', ''], 'transcript': [Lang.get_string("song_meta/transcript", self.locale) + ': ', ''], 'song_key': [Lang.get_string("song_meta/musical_key", self.locale) + ': ', ''] }
def check_delimiters(self): if self.input_mode == InputMode.JIANPU or isinstance( self.note_parser, src.skymusic.parsers.noteparsers.jianpu.Jianpu): if self.pause != Resources.JIANPU_PAUSE: if not self.silent_warnings: print('\n' + Lang.get_string("warnings/jianpu_pause", self.locale ).format(pause=self.pause)) self.pause = Resources.JIANPU_PAUSE if self.quaver_delimiter == '-': if not self.silent_warnings: print('\n' + Lang.get_string( "warnings/jianpu_quaver_delimiter", self.locale). format(jianpu_quaver_delimiter=Resources. JIANPU_QUAVER_DELIMITER, quaver_delimiter=self.quaver_delimiter)) self.quaver_delimiter = Resources.JIANPU_QUAVER_DELIMITER delims = [ self.icon_delimiter, self.pause, self.quaver_delimiter, self.comment_delimiter, self.repeat_indicator ] if self.quaver_delimiter == '\s' or re.match('\s', self.quaver_delimiter): print( "\n***ERROR: You cannot use a blank delimiter to separate notes in a quaver" ) if self.pause == '\s' or re.match('\s', self.pause): print( "\n***ERROR: You cannot use a blank delimiter to indicate a pause" ) if self.comment_delimiter == '\s' or re.match('\s', self.comment_delimiter): print( "\n***ERROR: You cannot use a blank delimiter to indicate comments" ) if self.comment_delimiter == '\s' or re.match('\s', self.repeat_indicator): print( "\n***ERROR: You cannot use a blank delimiter to indicate repetition" ) parser = self.get_note_parser() if parser is not None: for delim in delims: if (parser.not_note_name_regex.match(delim) is None or parser.not_octave_regex.match(delim) is None ) and delim != self.comment_delimiter: print( f"\n***ERROR: You chose an invalid delimiter for notation {self.input_mode.get_short_desc(self.locale)}: {delim}" ) if delims.count(delim) > 1: print( "\n***ERROR: You used the same delimiter for different purposes." )
def set_locale(self, locale): self.locale = Lang.check_locale(locale) if self.locale is None: self.locale = Lang.find_substitute(locale) print( f"**WARNING: bad locale type passed to CommandLinePlayer: {locale}. Reverting to {self.locale}" ) return self.locale
def set_locale(self, locale): self.locale = Lang.check_locale(locale) if self.locale is None: self.locale = Lang.guess_locale() print( f"**WARNING: bad locale type {locale} passed to MusicSheetMaker. Reverting to {self.locale}" ) return self.locale
def ask_song_metadata(self, recipient, prerequisites=None, execute=True): queries = [] replacements = { 'skip': Lang.get_string(f"recipient_specifics/skip/{recipient.get_name()}", self.locale) } queries += [ self.communicator.send_stock_query('song_title', recipient=recipient, replacements=replacements, prerequisites=prerequisites) ] queries += [ self.communicator.send_stock_query('original_artist', recipient=recipient, prerequisites=prerequisites) ] queries += [ self.communicator.send_stock_query('transcript_writer', replacements=replacements, recipient=recipient, prerequisites=prerequisites) ] if execute: recipient.execute_queries(queries) meta_data = [q.get_reply().get_result() for q in queries] return queries, tuple(meta_data) else: return queries, None
def ask_song_bpm(self, recipient, render_modes=None, prerequisites=None, execute=True): if render_modes is None: render_modes = self.retrieve_render_modes(recipient) time_modes = [RenderMode.MIDI] #TODO: add SkyJSON if not any([mode in render_modes for mode in time_modes]): return None, 120 else: replacements = { 'skip_number': Lang.get_string( f"recipient_specifics/skip_number/{recipient.get_name()}", self.locale) } q_song_bpm = self.communicator.send_stock_query( 'song_bpm', recipient=recipient, replacements=replacements, prerequisites=prerequisites) if execute: recipient.execute_queries(q_song_bpm) song_bpm = q_song_bpm.get_reply().get_result() return q_song_bpm, song_bpm else: return q_song_bpm, None
def set_locale(self, locale): self.locale = Lang.check_locale(locale) if self.locale is None: try: self.locale = Lang.check_locale(self.owner.get_locale()) except: pass if self.locale is None: self.locale = Lang.guess_locale() print( f"**WARNING: bad locale type {locale} passed to Communicator. Reverting to {self.locale}" ) return self.locale
def __init__(self, maker, silent_warnings=True): self.maker = maker self.silent_warnings = silent_warnings #Delimiters must be character or strings #The backslash character is forbidden #Only regex with the following format are supported: \x, where x is s, t, w, d, n, r, a, r, f, v, or R self.input_mode = None self.note_parser = None self.icon_delimiter = Resources.ICON_DELIMITER self.pause = Resources.PAUSE self.quaver_delimiter = Resources.QUAVER_DELIMITER self.comment_delimiter = Resources.COMMENT_DELIMITER self.repeat_indicator = Resources.REPEAT_INDICATOR self.skyjson_chord_delay = Resources.SKYJSON_CHORD_DELAY #Delay in ms below which 2 notes are considered a chord self.default_key = Resources.DEFAULT_KEY self.allowed_regex = [ '\s', '\t', '\w', '\d', '\n', '\r', '\a', '\e', '\f', '\v', '\R' ] self.music_theory = music_theory.MusicTheory(self) try: self.locale = self.maker.get_locale() except AttributeError: # Should never happen self.locale = Lang.guess_locale() print( f"**ERROR: SongParser self.maker has no locale. Reverting to {self.locale}" )
def build_file_paths(self, song, render_mode, numfiles, dir_out): """ Command line only : generates a list of file paths for a given input mode. """ if numfiles == 0: return [] sanitized_title = re.sub(r'[\\/:"*?<>|]', '', re.escape(song.get_title())).strip() sanitized_title = re.sub( '(\s)+', '_', sanitized_title) # replaces spaces by underscore sanitized_title = sanitized_title[:31] if len(sanitized_title) == 0 or sanitized_title == '_': sanitized_title = Lang.get_string("song_meta/untitled", self.locale) file_base = os.path.join(dir_out, sanitized_title) file_ext = render_mode.extension file_paths = [] if numfiles > 1: for i in range(numfiles): file_paths += [file_base + str(i) + file_ext] else: file_paths = [file_base + file_ext] return file_paths
def ask_aspect_ratio(self, recipient, render_modes=None, prerequisites=None, execute=True): if render_modes is None: render_modes = self.retrieve_render_modes(recipient) if not any([mode.get_is_image() for mode in render_modes]): return None, AspectRatio.WIDESCREEN else: replacements = { 'skip': Lang.get_string( f"recipient_specifics/skip/{recipient.get_name()}", self.locale) } q_aspect = self.communicator.send_stock_query( 'aspect_ratio', recipient=recipient, replacements=replacements, prerequisites=prerequisites) if execute: recipient.execute_queries(q_aspect) aspect_ratio = q_aspect.get_reply().get_result() return q_aspect, aspect_ratio else: return q_aspect, None
def ask_octave_shift(self, recipient, input_mode=None, prerequisites=None, execute=True): if input_mode is None: input_mode = self.retrieve_input_mode(recipient) if not input_mode.get_is_chromatic(): return None, 0 else: replacements = { 'skip_number': Lang.get_string( f"recipient_specifics/skip_number/{recipient.get_name()}", self.locale) } q_shift = self.communicator.send_stock_query( 'octave_shift', recipient=recipient, replacements=replacements, prerequisites=prerequisites) if execute: recipient.execute_queries(q_shift) octave_shift = q_shift.get_reply().get_result() return q_shift, octave_shift else: return q_shift, None
def __init__(self, locale=None): if locale is None: self.locale = Lang.guess_locale() print( f"**ERROR: Song self.maker has no locale. Reverting to: {self.locale}" ) else: self.locale = locale
def reply_to_website_result(self, reply): song_bundle = reply.get_result() # Should be a SongBundle object result_dict = {} result_dict.update({'song_meta': song_bundle.get_meta()}) result_dict.update({'song_files': []}) result_dict.update({'saves': []}) sanitized_title = re.sub(r'[\\/:"*?<>|]', '', re.escape( song_bundle.get_meta()['title'])).strip() sanitized_title = re.sub( '(\s)+', '_', sanitized_title) # replaces spaces by underscore sanitized_title = sanitized_title[:31] if len(sanitized_title) == 0 or sanitized_title == '_': sanitized_title = Lang.get_string("song_meta/untitled", self.locale) for render_mode, buffers in song_bundle.get_all_renders().items(): if not isinstance(render_mode, RenderMode): raise CommunicatorError( f"Unexpected type for song_bundle key:{type(render_mode)}") if not isinstance(buffers, (list, tuple)): raise CommunicatorError( f"Unexpected type for song_bundle value:{type(buffers)}") if not isinstance(buffers[0], (io.BytesIO, io.StringIO)): raise CommunicatorError( f"Unexpected type for song_bundle value:{type(buffers[0])}" ) result_dict['song_files'] += [{ 'file_type': render_mode.mime_type, 'base_name': sanitized_title + '_', 'number': i, 'ext': render_mode.extension } for i, buffer in enumerate(buffers)] result_dict['saves'] += [{ 'name': sanitized_title + '_' + str(i) + render_mode.extension, 'buffer': buffer } for i, buffer in enumerate(buffers)] return result_dict
def ask_notes(self, recipient, prerequisites=None, execute=True): replacements = { 'input_modes': '\n'.join([ '\n* ' + input_mode.get_long_desc(self.locale) for input_mode in InputMode ]), 'icon_delimiter': self.get_song_parser().get_icon_delimiter().replace( '\s', '<space>'), 'pause': self.get_song_parser().get_pause().replace('\s', '<space>'), 'quaver_delimiter': self.get_song_parser().get_quaver_delimiter().replace( '\s', '<space>'), 'quaver_example': self.get_song_parser().get_quaver_delimiter().replace( '\s', '<space>').join(['A1', 'B1', 'C1']), 'jianpu_quaver_delimiter': Resources.JIANPU_QUAVER_DELIMITER, 'repeat_indicator': self.get_song_parser().get_repeat_indicator() + '2' } replacements.update({ 'skip': Lang.get_string(f"recipient_specifics/skip/{recipient.get_name()}", self.locale) }) q_notes = self.communicator.send_stock_query( 'notes', recipient=recipient, replacements=replacements, prerequisites=prerequisites) if execute: recipient.execute_queries(q_notes) notes = q_notes.get_reply().get_result() return q_notes, notes else: return q_notes, None
def load(locale): return { # Queries asked by the Player / Music Cog 'create_song': { 'class': QueryOpen, 'handler': 'create_song', # The name of the method that must be executed by the recipient 'question': 'create_song', 'reply_type': ReplyType.OTHER }, # Generic Query 'information': { 'class': Information, 'handler': 'None', 'question': '', 'reply_type': ReplyType.TEXT }, 'instructions_command_line': { 'class': Information, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/instructions_command_line/foreword", locale), 'question': Lang.get_string("stock_queries/instructions_command_line/question", locale), 'afterword': Lang.get_string( "stock_queries/instructions_command_line/afterword", locale), 'input_tip': Lang.get_string( "stock_queries/instructions_command_line/input_tip", locale), 'help_text': Lang.get_string( "stock_queries/instructions_command_line/help_text", locale) }, 'instructions_sky_music_website': { 'class': Information, 'handler': 'None', 'foreword': Lang.get_string( "stock_queries/instructions_sky_music_website/foreword", locale), 'question': Lang.get_string( "stock_queries/instructions_sky_music_website/question", locale), 'afterword': Lang.get_string( "stock_queries/instructions_sky_music_website/afterword", locale), 'input_tip': Lang.get_string( "stock_queries/instructions_sky_music_website/input_tip", locale), 'help_text': Lang.get_string( "stock_queries/instructions_sky_music_website/help_text", locale) }, 'instructions_music_cog': { 'class': Information, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/instructions_music_cog/foreword", locale), 'question': Lang.get_string("stock_queries/instructions_music_cog/question", locale), 'afterword': Lang.get_string("stock_queries/instructions_music_cog/afterword", locale), 'input_tip': Lang.get_string("stock_queries/instructions_music_cog/input_tip", locale), 'help_text': Lang.get_string("stock_queries/instructions_music_cog/help_text", locale) }, 'render_modes': { 'class': QueryMultipleChoices, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/render_modes/foreword", locale), 'question': Lang.get_string("stock_queries/render_modes/question", locale), 'afterword': Lang.get_string("stock_queries/render_modes/afterword", locale), 'input_tip': Lang.get_string("stock_queries/render_modes/input_tip", locale), 'help_text': Lang.get_string("stock_queries/render_modes/help_text", locale), 'reply_type': ReplyType.RENDERMODES, 'limits': [], 'default': 'all' }, 'aspect_ratio': { 'class': QueryChoice, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/aspect_ratio/foreword", locale), 'question': Lang.get_string("stock_queries/aspect_ratio/question", locale), 'afterword': Lang.get_string("stock_queries/aspect_ratio/afterword", locale), 'input_tip': Lang.get_string("stock_queries/aspect_ratio/input_tip", locale), 'help_text': Lang.get_string("stock_queries/aspect_ratio/help_text", locale), 'reply_type': ReplyType.ASPECTRATIO, 'limits': list(AspectRatio), 'default': AspectRatio.WIDESCREEN }, 'song_bpm': { 'class': QueryOpen, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/song_bpm/foreword", locale), 'question': Lang.get_string("stock_queries/song_bpm/question", locale), 'afterword': Lang.get_string("stock_queries/song_bpm/afterword", locale), 'input_tip': Lang.get_string("stock_queries/song_bpm/input_tip", locale), 'help_text': Lang.get_string("stock_queries/song_bpm/help_text", locale), 'reply_type': ReplyType.NUMBER, 'limits': [12, 1200], 'default': 120 }, 'song_title': { 'class': QueryOpen, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/song_title/foreword", locale), 'question': Lang.get_string("stock_queries/song_title/question", locale), 'afterword': Lang.get_string("stock_queries/song_title/afterword", locale), 'input_tip': Lang.get_string("stock_queries/song_title/input_tip", locale), 'help_text': Lang.get_string("stock_queries/song_title/help_text", locale), 'reply_type': ReplyType.TEXT, 'limits': None, 'default': Lang.get_string("song_meta/untitled", locale) }, 'original_artist': { 'class': QueryOpen, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/original_artist/foreword", locale), 'question': Lang.get_string("stock_queries/original_artist/question", locale), 'afterword': Lang.get_string("stock_queries/original_artist/afterword", locale), 'input_tip': Lang.get_string("stock_queries/original_artist/input_tip", locale), 'help_text': Lang.get_string("stock_queries/original_artist/help_text", locale), 'reply_type': ReplyType.TEXT, 'limits': None, 'default': None #Required by Discord }, 'transcript_writer': { 'class': QueryOpen, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/transcript_writer/foreword", locale), 'question': Lang.get_string("stock_queries/transcript_writer/question", locale), 'afterword': Lang.get_string("stock_queries/transcript_writer/afterword", locale), 'input_tip': Lang.get_string("stock_queries/transcript_writer/input_tip", locale), 'help_text': Lang.get_string("stock_queries/transcript_writer/help_text", locale), 'reply_type': ReplyType.TEXT, 'limits': None, 'default': '' }, 'notes_file': { 'class': QueryOpen, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/notes_file/foreword", locale), 'question': Lang.get_string("stock_queries/notes_file/question", locale), 'afterword': Lang.get_string("stock_queries/notes_file/afterword", locale), 'input_tip': Lang.get_string("stock_queries/notes_file/input_tip", locale), 'help_text': Lang.get_string("stock_queries/notes_file/help_text", locale), 'reply_type': ReplyType.OTHER, 'expect_long_answer': True, 'limits': None }, 'file': { 'class': QueryOpen, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/file/foreword", locale), 'question': Lang.get_string("stock_queries/file/question", locale), 'afterword': Lang.get_string("stock_queries/file/afterword", locale), 'input_tip': Lang.get_string("stock_queries/file/input_tip", locale), 'help_text': Lang.get_string("stock_queries/file/help_text", locale), 'reply_type': ReplyType.FILEPATH, 'limits': '.' }, 'notes': { 'class': QueryOpen, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/notes/foreword", locale), 'question': Lang.get_string("stock_queries/notes/question", locale), 'afterword': Lang.get_string("stock_queries/notes/afterword", locale), 'input_tip': Lang.get_string("stock_queries/notes/input_tip", locale), 'help_text': Lang.get_string("stock_queries/notes/help_text", locale), 'reply_type': ReplyType.TEXT, 'expect_long_answer': True, 'limits': None, 'default': '' }, 'one_input_mode': { 'class': Information, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/one_input_mode/foreword", locale), 'question': Lang.get_string("stock_queries/one_input_mode/question", locale), 'afterword': Lang.get_string("stock_queries/one_input_mode/afterword", locale), 'input_tip': Lang.get_string("stock_queries/one_input_mode/input_tip", locale), 'help_text': Lang.get_string("stock_queries/one_input_mode/help_text", locale) }, 'musical_notation': { 'class': QueryChoice, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/musical_notation/foreword", locale), 'question': Lang.get_string("stock_queries/musical_notation/question", locale), 'afterword': Lang.get_string("stock_queries/musical_notation/afterword", locale), 'input_tip': Lang.get_string("stock_queries/musical_notation/input_tip", locale), 'help_text': Lang.get_string("stock_queries/musical_notation/help_text", locale), 'reply_type': ReplyType.INPUTMODE, 'limits': [] }, 'no_possible_key': { 'class': Information, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/no_possible_key/foreword", locale), 'question': Lang.get_string("stock_queries/no_possible_key/question", locale), 'afterword': Lang.get_string("stock_queries/no_possible_key/afterword", locale), 'input_tip': Lang.get_string("stock_queries/no_possible_key/input_tip", locale), 'help_text': Lang.get_string("stock_queries/no_possible_key/help_text", locale) }, 'one_possible_key': { 'class': Information, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/one_possible_key/foreword", locale), 'question': Lang.get_string("stock_queries/one_possible_key/question", locale), 'afterword': Lang.get_string("stock_queries/one_possible_key/afterword", locale), 'input_tip': Lang.get_string("stock_queries/one_possible_key/input_tip", locale), 'help_text': Lang.get_string("stock_queries/one_possible_key/help_text", locale) }, 'possible_keys': { 'class': QueryChoice, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/possible_keys/foreword", locale), 'question': Lang.get_string("stock_queries/possible_keys/question", locale), 'afterword': Lang.get_string("stock_queries/possible_keys/afterword", locale), 'input_tip': Lang.get_string("stock_queries/possible_keys/input_tip", locale), 'help_text': Lang.get_string("stock_queries/possible_keys/help_text", locale), 'reply_type': ReplyType.NOTE, 'limits': [] }, 'recommended_key': { 'class': QueryOpen, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/recommended_key/foreword", locale), 'question': Lang.get_string("stock_queries/recommended_key/question", locale), 'afterword': Lang.get_string("stock_queries/recommended_key/afterword", locale), 'input_tip': Lang.get_string("stock_queries/recommended_key/input_tip", locale), 'help_text': Lang.get_string("stock_queries/recommended_key/help_text", locale), 'reply_type': ReplyType.NOTE, 'limits': None, 'default': 'C' }, 'octave_shift': { 'class': QueryOpen, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/octave_shift/foreword", locale), 'question': Lang.get_string("stock_queries/octave_shift/question", locale), 'afterword': Lang.get_string("stock_queries/octave_shift/afterword", locale), 'input_tip': Lang.get_string("stock_queries/octave_shift/input_tip", locale), 'help_text': Lang.get_string("stock_queries/octave_shift/help_text", locale), 'reply_type': ReplyType.NUMBER, 'limits': [-6, 6], 'default': 0 }, 'one_song_file': { 'class': Information, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/one_song_file/foreword", locale), 'question': Lang.get_string("stock_queries/one_song_file/question", locale), 'afterword': Lang.get_string("stock_queries/one_song_file/afterword", locale), 'input_tip': Lang.get_string("stock_queries/one_song_file/input_tip", locale), 'help_text': Lang.get_string("stock_queries/one_song_file/help_text", locale) }, 'several_song_files': { 'class': Information, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/several_song_files/foreword", locale), 'question': Lang.get_string("stock_queries/several_song_files/question", locale), 'afterword': Lang.get_string("stock_queries/several_song_files/afterword", locale), 'input_tip': Lang.get_string("stock_queries/several_song_files/input_tip", locale), 'help_text': Lang.get_string("stock_queries/several_song_files/help_text", locale) }, 'no_song_file': { 'class': Information, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/no_song_file/foreword", locale), 'question': Lang.get_string("stock_queries/no_song_file/question", locale), 'afterword': Lang.get_string("stock_queries/no_song_file/afterword", locale), 'input_tip': Lang.get_string("stock_queries/no_song_file/input_tip", locale), 'help_text': Lang.get_string("stock_queries/no_song_file/help_text", locale) }, 'few_errors': { 'class': Information, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/few_errors/foreword", locale), 'question': Lang.get_string("stock_queries/few_errors/question", locale), 'afterword': Lang.get_string("stock_queries/few_errors/afterword", locale), 'input_tip': Lang.get_string("stock_queries/few_errors/input_tip", locale), 'help_text': Lang.get_string("stock_queries/few_errors/help_text", locale) }, 'many_errors': { 'class': Information, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/many_errors/foreword", locale), 'question': Lang.get_string("stock_queries/many_errors/question", locale), 'afterword': Lang.get_string("stock_queries/many_errors/afterword", locale), 'input_tip': Lang.get_string("stock_queries/many_errors/input_tip", locale), 'help_text': Lang.get_string("stock_queries/many_errors/help_text", locale) }, }
def get_short_desc(self, locale='en_US'): return Lang.get_string(self.short_desc_yaml, locale)
def get_long_desc(self, locale='en_US'): return Lang.get_string(self.long_desc_yaml, locale)
def ask_notes_or_file(self, recipient, prerequisites=None, execute=True): """ Asks for notes (all recipients) or a file name (command-line only) If a file name is detected but the file does not exist, sends a query to ask for a valid file path If notes are detected, return the notes as a list of strings splitted by the OS line separator """ replacements = { 'input_modes': '\n'.join([ '\n* ' + input_mode.get_long_desc(self.locale) for input_mode in InputMode ]), 'icon_delimiter': self.get_song_parser().get_icon_delimiter().replace( '\s', '<space>'), 'pause': self.get_song_parser().get_pause().replace('\s', '<space>'), 'quaver_delimiter': self.get_song_parser().get_quaver_delimiter().replace( '\s', '<space>'), 'quaver_example': self.get_song_parser().get_quaver_delimiter().replace( '\s', '<space>').join(['A1', 'B1', 'C1']), 'jianpu_quaver_delimiter': Resources.JIANPU_QUAVER_DELIMITER, 'repeat_indicator': self.get_song_parser().get_repeat_indicator() + '2' } if not self.is_command_line(recipient): return self.ask_notes(recipient=recipient, prerequisites=prerequisites, execute=execute) else: replacements.update({ 'songs_in': os.path.relpath(os.path.normpath(self.song_dir_in)) }) q_notes = self.communicator.send_stock_query( 'notes_file', recipient=recipient, replacements=replacements, prerequisites=prerequisites) if not execute: return q_notes, None else: recipient.execute_queries(q_notes) result = q_notes.get_reply().get_result() if self.is_command_line(recipient): # Detects if the result is a file path file_path = os.path.join(self.song_dir_in, os.path.normpath(result)) isfile = os.path.isfile(file_path) if not isfile: splitted = os.path.splitext(result) if len(splitted[0]) > 0 and 2 < len( splitted[1]) <= 5 and re.search( '\\.', splitted[0]) is None: # then certainly a file name self.communicator.memory.erase(q_notes) q_notes, file_path = self.ask_file( recipient=recipient, prerequisites=prerequisites, execute=execute) isfile = True # ask_file only returns when a valid file path is found else: isfile = False # Don't allow reading files on the website or music-cog if isfile and self.is_command_line(recipient): notes = self.read_file(file_path) print( Lang.get_string("open_file", self.locale).format( file_path=os.path.abspath(file_path))) else: notes = result.split( os.linesep) # Returns a list of strings in any case if self.is_command_line( recipient ): # Loop to ask for several lines in the standard input interface while result: (q_notes, result) = self.ask_notes( recipient=recipient, prerequisites=prerequisites, execute=execute) result = result.split(os.linesep) for result in result: notes.append(result) return q_notes, notes
print(f"\n{question}: {answer}") q.reply_to(answer) if answer is None: # Else asks the user a question in the prompt answer = input('%s: ' % question) q.reply_to(answer) reply_valid = q.get_reply_validity() else: print('\n' + question) q.reply_to('ok') reply_valid = q.get_reply_validity() try: player = CommandLinePlayer(locale=Lang.guess_locale(), preferences_path=PREFERENCES_PATH) maker = MusicSheetMaker(locale=Lang.guess_locale(), song_dir_in=SONG_DIR_IN, song_dir_out=SONG_DIR_OUT) if BATCH_MODE: file_paths = player.fetch_yaml_songs(BATCH_DIR) for file_path in file_paths: player.load_yaml_song(file_path) q = player.communicator.send_stock_query('create_song', recipient=maker) maker.execute_queries(q) maker.communicator.flush() player.communicator.flush()
def ask_song_key(self, recipient, notes=None, input_mode=None, prerequisites=None, execute=True): """ Attempts to detect key for input written in absolute musical scales (western, Jianpu) """ # EXPERIMENTAL if notes is None: notes = self.retrieve_notes(recipient) if input_mode is None: input_mode = self.retrieve_input_mode(recipient, notes) song_key = None possible_keys = self.get_song_parser().find_key(notes) try: default_key = self.get_song_parser().get_default_key() except AttributeError: default_key = 'C' if possible_keys is None: # Asks for any text string replacements = { 'skip': Lang.get_string( f"recipient_specifics/skip/{recipient.get_name()}", self.locale), 'song_key': default_key } q_key = self.communicator.send_stock_query( 'recommended_key', recipient=recipient, replacements=replacements, prerequisites=prerequisites) elif len(possible_keys) == 0: # Sends information that there is no possible key q_key = self.communicator.send_stock_query( 'no_possible_key', recipient=recipient, replacements={'song_key': default_key}, prerequisites=prerequisites) possible_keys = [default_key] elif len(possible_keys) == 1: # Sends information that there is only 1 possible key q_key = self.communicator.send_stock_query( 'one_possible_key', recipient=recipient, replacements={'song_key': str(possible_keys[0])}, prerequisites=prerequisites) else: # Asks to choose a key within a list q_key = self.communicator.send_stock_query( 'possible_keys', recipient=recipient, replacements={'song_key': ', '.join(possible_keys)}, limits=possible_keys, prerequisites=prerequisites) if execute: recipient.execute_queries(q_key) if possible_keys is None: song_key = q_key.get_reply().get_result() if len(song_key.strip()) == 0: song_key = default_key elif len(possible_keys) == 1: song_key = possible_keys[0] elif len(possible_keys) > 1: song_key = q_key.get_reply().get_result() else: raise MusicSheetMakerError("Possible keys is an empty list.") return q_key, song_key else: # Not execute if possible_keys is None: song_key = None elif len(possible_keys) == 1: song_key = possible_keys[0] else: song_key = None return q_key, song_key