def check_delimiters(self): if self.input_mode == InputMode.JIANPU or isinstance(self.note_parser, 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.lyric_delimiter, self.repeat_indicator, self.metadata_delimiter] 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.lyric_delimiter == '\s' or re.match('\s', self.lyric_delimiter): print("\n***ERROR: You cannot use a blank delimiter to indicate lyrics") if self.metadata_delimiter == '\s' or re.match('\s', self.metadata_delimiter): print("\n***ERROR: You cannot use a blank delimiter to indicate metadata") if self.lyric_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 not in [self.lyric_delimiter, self.metadata_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 __init__(self, locale=None, music_key=Resources.DEFAULT_KEY): 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) + ': ', ''] } self.is_meta_changed = False
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 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 __init__(self, maker, silent_warnings=True): self.maker = maker self.instrument_type = InstrumentType.NORMAL 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.lyric_delimiter = Resources.LYRIC_DELIMITER self.metadata_delimiter = Resources.METADATA_DELIMITER self.repeat_indicator = Resources.REPEAT_INDICATOR 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 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 generate_url(self, json_buffer, api_key=Resources.skyjson_api_key): # clears the sys.meta_path cache to reload packages(directory), does not really apply to top-level libraries importlib.invalidate_caches() try: import requests except (ImportError, ModuleNotFoundError): print( "\n***WARNING: 'requests' package not installed: could not generate temp link to sky-music.herokuapp.com" ) else: json_buffer.seek(0) json_dict = json.load(json_buffer) json_dict = {'API_KEY': api_key, 'song': json_dict} headers = { 'Content-type': 'application/json', 'Accept': 'text/plain' } try: rep = requests.post(url=Resources.skyjson_api_url, json=json_dict, headers=headers, timeout=5) url = rep.text except (requests.ConnectionError, requests.HTTPError, requests.exceptions.ReadTimeout) as err: print('\n*** WARNING:' + Lang.get_string( "warnings/skyjson_url_connection", self.locale) + ':') print(err) url = None return url
def ask_render_modes(self, recipient, prerequisites=None, execute=True): """ Asks for the desired render modes for the Song """ render_modes = self.render_modes_enabled if len(render_modes) == 1: return None, render_modes if self.is_music_cog(recipient): return None, self.music_cog_render_modes else: replacements = {'all_modes': Lang.get_string(f"recipient_specifics/all_modes/{recipient.get_name()}", self.locale)} q_render = self.communicator.send_stock_query('render_modes', recipient=recipient, limits=render_modes, replacements=replacements, prerequisites=prerequisites) if execute: recipient.execute_queries(q_render) render_modes = q_render.get_reply().get_result() return q_render, render_modes else: return q_render, 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 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_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_file(self, recipient, prerequisites=None, execute=True): replacements = {'songs_in': self.shortest_path(self.song_in_dir), 'put_in_songs_in': Lang.get_string(f"recipient_specifics/put_in_songs_in/{recipient.get_name()}", self.locale) } q_file = self.communicator.send_stock_query('file', recipient=recipient, replacements=replacements, prerequisites=prerequisites, limits=(os.path.normpath(self.song_in_dir))) if execute: recipient.execute_queries(q_file) file_name = q_file.get_reply().get_result() file_path = os.path.join(self.song_in_dir, os.path.normpath(file_name)) return q_file, file_path # should return file name else: return q_file, None
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_filename = song_bundle.get_sanitized_song_filename() if len(sanitized_filename) == 0: sanitized_filename = Lang.get_string("song_meta/untitled", self.locale) for render_mode, buffers in song_bundle.get_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_filename + '_', 'number': i, 'ext': render_mode.extension } for i, buffer in enumerate(buffers)] result_dict['saves'] += [{ 'name': sanitized_filename + '_' + 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 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.get_time_modes() #if not any([mode in render_modes for mode in time_modes]): if not any([mode.get_is_time() for mode in render_modes]): return None, Resources.DEFAULT_BPM 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
if answer is not None: print(f"\n{question}: {answer}") q.reply_to(answer) if answer is None: # Else asks the user a question in the prompt answer = input(f"{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(), application_root=application_root, song_in_dir=SONG_IN_DIR, song_out_dir=SONG_OUT_DIR, skyjson_url_api=(SKYJSON_URL if not BATCH_MODE else None)) 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)
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' } replacements.update({'put_in_songs_in': Lang.get_string(f"recipient_specifics/put_in_songs_in/{recipient.get_name()}", self.locale)}) if self.is_music_cog(recipient): return self.ask_notes(recipient=recipient, prerequisites=prerequisites, execute=execute) else: replacements.update({'songs_in': self.shortest_path(self.song_in_dir)}) 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_music_cog(recipient): isfile = False # Don't allow reading files stored on system path on the music-cog else: # Detects if the result is a file path file_path = os.path.join(self.song_in_dir, 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 if isfile: notes = self.read_file(file_path) if self.is_command_line(recipient): 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
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 }, 'instrument_type': { 'class': QueryChoice, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/instrument_type/foreword", locale), 'question': Lang.get_string("stock_queries/instrument_type/question", locale), 'afterword': Lang.get_string("stock_queries/instrument_type/afterword", locale), 'input_tip': Lang.get_string("stock_queries/instrument_type/input_tip", locale), 'help_text': Lang.get_string("stock_queries/instrument_type/help_text", locale), 'reply_type': ReplyType.INSTRUMENT, 'limits': list(InstrumentType), 'default': InstrumentType.NORMAL }, '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': 220 }, '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': [] }, 'keep_meta': { 'class': QueryBoolean, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/keep_meta/foreword", locale), 'question': Lang.get_string("stock_queries/keep_meta/question", locale), 'afterword': Lang.get_string("stock_queries/keep_meta/afterword", locale), 'input_tip': Lang.get_string("stock_queries/keep_meta/input_tip", locale), 'help_text': Lang.get_string("stock_queries/keep_meta/help_text", locale), 'reply_type': ReplyType.TEXT, 'limits': [ Lang.get_string("words/yes_word", locale), Lang.get_string("words/no_word", locale) ] }, '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': QueryBoolean, '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), 'reply_type': ReplyType.TEXT, 'limits': [ Lang.get_string("words/yes_word", locale), Lang.get_string("words/no_word", locale) ] }, 'empty_song': { 'class': QueryBoolean, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/empty_song/foreword", locale), 'question': Lang.get_string("stock_queries/empty_song/question", locale), 'afterword': Lang.get_string("stock_queries/empty_song/afterword", locale), 'input_tip': Lang.get_string("stock_queries/empty_song/input_tip", locale), 'help_text': Lang.get_string("stock_queries/empty_song/help_text", locale), 'reply_type': ReplyType.TEXT, 'limits': [ Lang.get_string("words/yes_word", locale), Lang.get_string("words/no_word", locale) ] }, 'skyjson_url': { 'class': Information, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/skyjson_url/foreword", locale), 'question': Lang.get_string("stock_queries/skyjson_url/question", locale), 'afterword': Lang.get_string("stock_queries/skyjson_url/afterword", locale), 'input_tip': Lang.get_string("stock_queries/skyjson_url/input_tip", locale), 'help_text': Lang.get_string("stock_queries/skyjson_url/help_text", locale) }, 'discord_ad': { 'class': Information, 'handler': 'None', 'foreword': Lang.get_string("stock_queries/discord_ad/foreword", locale), 'question': Lang.get_string("stock_queries/discord_ad/question", locale), 'afterword': Lang.get_string("stock_queries/discord_ad/afterword", locale), 'input_tip': Lang.get_string("stock_queries/discord_ad/input_tip", locale), 'help_text': Lang.get_string("stock_queries/discord_ad/help_text", locale) } }
def get_long_desc(self, locale='en_US'): return Lang.get_string(self.long_desc_yaml, locale)
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 = Resources.DEFAULT_KEY 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
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: recommended_octave_shift = '{:d}/{:d}'.format(Resources.PARSING_START_OCTAVE - 3, Resources.PARSING_START_OCTAVE - 4) replacements = {'recommended_octave_shift': recommended_octave_shift, '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 get_short_desc(self, locale='en_US'): return Lang.get_string(self.short_desc_yaml, locale)