import os import gradio as gr import json import shutil from tts_webui.history_tab.delete_generation import delete_generation from tts_webui.history_tab.collections_directories_atom import ( collections_directories_atom, get_collections, ) from tts_webui.history_tab.get_wav_files import get_wav_files from tts_webui.history_tab.delete_generation_cb import delete_generation_cb from tts_webui.history_tab.save_to_favorites import ( save_to_collection, save_to_favorites, ) from tts_webui.history_tab.open_folder import open_folder def _get_row_index(evt: gr.SelectData): index: int | tuple[int, int] = evt.index return index[0] if isinstance(index, (list, tuple)) else index def _get_filename(table, index): return table["data"][index][-1] def get_json_text(filename): try: with open(filename) as f: return json.load(f) except: return None def _select_audio(table, evt: gr.SelectData): index = _get_row_index(evt) filename = _get_filename(table, index) return filename, get_json_text(filename.replace(".wav", ".json")) def clear_audio(): return [ gr.Audio(value=None), gr.Image(value=None), gr.JSON(value=None), gr.Button(visible=False), ] def save_to_voices_cb(npz_filename: str): shutil.copy(npz_filename, "voices/") return gr.Button(value="Saved") def history_tab(directory="outputs", show_collections=False): with gr.Tab( show_collections and "Collections" or directory.capitalize() ) as history_tab: return history_content(directory, history_tab, show_collections) def history_content(directory, history_tab, show_collections): directories = get_collections() directory_dropdown = gr.Dropdown( value=directory, choices=directories, label="Select directory of the collection", visible=show_collections, ) collections_directories_atom.change( fn=lambda x: gr.Dropdown(choices=x), inputs=[collections_directories_atom], outputs=[directory_dropdown], ) if show_collections: create_collection_ui(collections_directories_atom) # with gr.Accordion("Gallery Selector (Click to Open)", open=False): # history_list_as_gallery = gr.Gallery( # value=[], columns=8, object_fit="contain", height="auto" # ) with gr.Row(): with gr.Column(): with gr.Row(): button_output = gr.Button( value=f"Open {show_collections and 'collection' or directory} folder" ) reload_button = gr.Button(value="Refresh", variant="secondary") button_output.click( lambda x: open_folder(x), inputs=[directory_dropdown], api_name=directory == "favorites" and "open_folder" or None, ) datatypes = ["date", "str", "str", "str"] # headers = ["Date and Time", directory.capitalize(), "When", "Filename"] headers = ["Date and Time", "Name", "When", "Filename"] history_list = gr.Dataframe( value=[], elem_classes="file-list", type="array", interactive=False, col_count=len(datatypes), datatype=datatypes, headers=headers, max_height=800, ) with gr.Column(): history_bundle_name = gr.Markdown(visible=True) folder_root = gr.Textbox(visible=False) history_audio = gr.Audio(visible=True, type="filepath", show_label=False) history_image = gr.Image(show_label=False) history_json = gr.JSON() history_npz = gr.Textbox(visible=False) with gr.Row(): delete_from_history = gr.Button( value="Delete", variant="stop", visible=False ) save_to_favorites_history = gr.Button( value="Save to favorites", variant="primary", visible=False ) gr.Markdown("""Use as voice button is now only available in React UI""") save_to_voices = gr.Button( value="Save to voices", variant="secondary", visible=False ) open_folder_button = gr.Button( value="Open folder", variant="secondary", visible=False ) open_folder_button.click(open_folder, inputs=folder_root) save_to_favorites_history.click( fn=save_to_favorites, inputs=folder_root, outputs=save_to_favorites_history, ) save_to_voices.click( fn=save_to_voices_cb, inputs=history_npz, outputs=save_to_voices, api_name=directory == "favorites" and "save_to_voices" or None, ) save_to_collection_ui( directory, directories, folder_root, collections_directories_atom, ) def _select_audio_history(filename: str, json_text): return { history_bundle_name: gr.Textbox(value=os.path.dirname(filename)), folder_root: os.path.dirname(filename), history_audio: gr.Audio(value=filename, label=filename), history_image: ( gr.Image(value=filename.replace(".wav", ".png")) if os.path.exists(filename.replace(".wav", ".png")) else gr.Image(value=None) ), history_json: gr.JSON(value=json_text), history_npz: gr.Textbox(value=filename.replace(".wav", ".npz")), delete_from_history: gr.Button(visible=True), save_to_favorites_history: gr.Button( visible=directory != "favorites", value="Save to favorites" ), save_to_voices: gr.Button(visible=True, value="Save to voices"), open_folder_button: gr.Button(visible=True), } def select_audio_history(table, evt: gr.SelectData): return _select_audio_history(*_select_audio(table, evt)) def select_audio_history2(_list, evt: gr.SelectData, table): return _select_audio_history(*_select_audio(table, evt)) outputs = [ history_bundle_name, folder_root, history_audio, history_image, history_json, history_npz, delete_from_history, save_to_favorites_history, save_to_voices, open_folder_button, ] history_list.select( fn=select_audio_history, inputs=[history_list], outputs=outputs, preprocess=False, ) def update_history_tab(directory: str): return gr.Dataframe(value=get_wav_files(directory)) delete_from_history.click( fn=clear_audio, outputs=[history_audio, history_image, history_json, delete_from_history], ) delete_from_history.click( fn=delete_generation_cb(update_history_tab), inputs=[folder_root, directory_dropdown], # outputs=[history_list, history_list_as_gallery], outputs=[history_list], ) # API ONLY gr.Button( value="Delete (API ONLY)", visible=False, ).click( fn=delete_generation, inputs=[folder_root], api_name=directory == "favorites" and "delete_generation" or None, ) history_tab.select( fn=update_history_tab, inputs=[directory_dropdown], # outputs=[history_list, history_list_as_gallery], outputs=[history_list], ) directory_dropdown.change( fn=update_history_tab, inputs=[directory_dropdown], # outputs=[history_list, history_list_as_gallery], outputs=[history_list], ) reload_button.click( fn=lambda x: gr.Dataframe(value=get_wav_files(x)), inputs=[directory_dropdown], outputs=[history_list], api_name=f"{'collections' if show_collections else directory}_refresh_history", ) def save_to_collection_ui( directory: str, directories: list[str], folder_root: gr.Textbox, directories_state: gr.JSON, ): with gr.Row(): move_to_collection = gr.Dropdown( label="Save to collection", choices=directories, value=directory, ) move_to_collection.select( fn=save_to_collection, inputs=[folder_root, move_to_collection], outputs=[move_to_collection], ) directories_state.change( fn=lambda x: gr.Dropdown(choices=x), inputs=[directories_state], outputs=[move_to_collection], ) def create_collection_ui(directories_state): new_collection_name = gr.Textbox(label="New collection name", value="") def create_collection(new_collection_name): os.makedirs(os.path.join("collections", new_collection_name)) return [ get_collections(), gr.Button(value="Created"), ] create_collection_button = gr.Button(value="Create collection") new_collection_name.change( fn=lambda: gr.Button(value="Create collection"), outputs=[create_collection_button], ) create_collection_button.click( fn=create_collection, inputs=[new_collection_name], outputs=[directories_state, create_collection_button], )