main.py 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. import os
  2. import gradio as gr
  3. import json
  4. import shutil
  5. from tts_webui.history_tab.delete_generation import delete_generation
  6. from tts_webui.history_tab.collections_directories_atom import (
  7. collections_directories_atom,
  8. get_collections,
  9. )
  10. from tts_webui.history_tab.get_wav_files import get_wav_files
  11. from tts_webui.history_tab.delete_generation_cb import delete_generation_cb
  12. from tts_webui.history_tab.save_to_favorites import (
  13. save_to_collection,
  14. save_to_favorites,
  15. )
  16. from tts_webui.history_tab.open_folder import open_folder
  17. def _get_row_index(evt: gr.SelectData):
  18. index: int | tuple[int, int] = evt.index
  19. return index[0] if isinstance(index, (list, tuple)) else index
  20. def _get_filename(table, index):
  21. return table["data"][index][-1]
  22. def get_json_text(filename):
  23. try:
  24. with open(filename) as f:
  25. return json.load(f)
  26. except:
  27. return None
  28. def _select_audio(table, evt: gr.SelectData):
  29. index = _get_row_index(evt)
  30. filename = _get_filename(table, index)
  31. return filename, get_json_text(filename.replace(".wav", ".json"))
  32. def clear_audio():
  33. return [
  34. gr.Audio(value=None),
  35. gr.Image(value=None),
  36. gr.JSON(value=None),
  37. gr.Button(visible=False),
  38. ]
  39. def save_to_voices_cb(npz_filename: str):
  40. shutil.copy(npz_filename, "voices/")
  41. return gr.Button(value="Saved")
  42. def history_tab(directory="outputs", show_collections=False):
  43. with gr.Tab(
  44. show_collections and "Collections" or directory.capitalize()
  45. ) as history_tab:
  46. return history_content(directory, history_tab, show_collections)
  47. def history_content(directory, history_tab, show_collections):
  48. directories = get_collections()
  49. directory_dropdown = gr.Dropdown(
  50. value=directory,
  51. choices=directories,
  52. label="Select directory of the collection",
  53. visible=show_collections,
  54. )
  55. collections_directories_atom.change(
  56. fn=lambda x: gr.Dropdown(choices=x),
  57. inputs=[collections_directories_atom],
  58. outputs=[directory_dropdown],
  59. )
  60. if show_collections:
  61. create_collection_ui(collections_directories_atom)
  62. # with gr.Accordion("Gallery Selector (Click to Open)", open=False):
  63. # history_list_as_gallery = gr.Gallery(
  64. # value=[], columns=8, object_fit="contain", height="auto"
  65. # )
  66. with gr.Row():
  67. with gr.Column():
  68. with gr.Row():
  69. button_output = gr.Button(
  70. value=f"Open {show_collections and 'collection' or directory} folder"
  71. )
  72. reload_button = gr.Button(value="Refresh", variant="secondary")
  73. button_output.click(
  74. lambda x: open_folder(x),
  75. inputs=[directory_dropdown],
  76. api_name=directory == "favorites" and "open_folder" or None,
  77. )
  78. datatypes = ["date", "str", "str", "str"]
  79. # headers = ["Date and Time", directory.capitalize(), "When", "Filename"]
  80. headers = ["Date and Time", "Name", "When", "Filename"]
  81. history_list = gr.Dataframe(
  82. value=[],
  83. elem_classes="file-list",
  84. type="array",
  85. interactive=False,
  86. col_count=len(datatypes),
  87. datatype=datatypes,
  88. headers=headers,
  89. max_height=800,
  90. )
  91. with gr.Column():
  92. history_bundle_name = gr.Markdown(visible=True)
  93. folder_root = gr.Textbox(visible=False)
  94. history_audio = gr.Audio(visible=True, type="filepath", show_label=False)
  95. history_image = gr.Image(show_label=False)
  96. history_json = gr.JSON()
  97. history_npz = gr.Textbox(visible=False)
  98. with gr.Row():
  99. delete_from_history = gr.Button(
  100. value="Delete", variant="stop", visible=False
  101. )
  102. save_to_favorites_history = gr.Button(
  103. value="Save to favorites", variant="primary", visible=False
  104. )
  105. gr.Markdown("""Use as voice button is now only available in React UI""")
  106. save_to_voices = gr.Button(
  107. value="Save to voices", variant="secondary", visible=False
  108. )
  109. open_folder_button = gr.Button(
  110. value="Open folder", variant="secondary", visible=False
  111. )
  112. open_folder_button.click(open_folder, inputs=folder_root)
  113. save_to_favorites_history.click(
  114. fn=save_to_favorites,
  115. inputs=folder_root,
  116. outputs=save_to_favorites_history,
  117. )
  118. save_to_voices.click(
  119. fn=save_to_voices_cb,
  120. inputs=history_npz,
  121. outputs=save_to_voices,
  122. api_name=directory == "favorites" and "save_to_voices" or None,
  123. )
  124. save_to_collection_ui(
  125. directory,
  126. directories,
  127. folder_root,
  128. collections_directories_atom,
  129. )
  130. def _select_audio_history(filename: str, json_text):
  131. return {
  132. history_bundle_name: gr.Textbox(value=os.path.dirname(filename)),
  133. folder_root: os.path.dirname(filename),
  134. history_audio: gr.Audio(value=filename, label=filename),
  135. history_image: (
  136. gr.Image(value=filename.replace(".wav", ".png"))
  137. if os.path.exists(filename.replace(".wav", ".png"))
  138. else gr.Image(value=None)
  139. ),
  140. history_json: gr.JSON(value=json_text),
  141. history_npz: gr.Textbox(value=filename.replace(".wav", ".npz")),
  142. delete_from_history: gr.Button(visible=True),
  143. save_to_favorites_history: gr.Button(
  144. visible=directory != "favorites", value="Save to favorites"
  145. ),
  146. save_to_voices: gr.Button(visible=True, value="Save to voices"),
  147. open_folder_button: gr.Button(visible=True),
  148. }
  149. def select_audio_history(table, evt: gr.SelectData):
  150. return _select_audio_history(*_select_audio(table, evt))
  151. def select_audio_history2(_list, evt: gr.SelectData, table):
  152. return _select_audio_history(*_select_audio(table, evt))
  153. outputs = [
  154. history_bundle_name,
  155. folder_root,
  156. history_audio,
  157. history_image,
  158. history_json,
  159. history_npz,
  160. delete_from_history,
  161. save_to_favorites_history,
  162. save_to_voices,
  163. open_folder_button,
  164. ]
  165. history_list.select(
  166. fn=select_audio_history,
  167. inputs=[history_list],
  168. outputs=outputs,
  169. preprocess=False,
  170. )
  171. def update_history_tab(directory: str):
  172. return gr.Dataframe(value=get_wav_files(directory))
  173. delete_from_history.click(
  174. fn=clear_audio,
  175. outputs=[history_audio, history_image, history_json, delete_from_history],
  176. )
  177. delete_from_history.click(
  178. fn=delete_generation_cb(update_history_tab),
  179. inputs=[folder_root, directory_dropdown],
  180. # outputs=[history_list, history_list_as_gallery],
  181. outputs=[history_list],
  182. )
  183. # API ONLY
  184. gr.Button(
  185. value="Delete (API ONLY)",
  186. visible=False,
  187. ).click(
  188. fn=delete_generation,
  189. inputs=[folder_root],
  190. api_name=directory == "favorites" and "delete_generation" or None,
  191. )
  192. history_tab.select(
  193. fn=update_history_tab,
  194. inputs=[directory_dropdown],
  195. # outputs=[history_list, history_list_as_gallery],
  196. outputs=[history_list],
  197. )
  198. directory_dropdown.change(
  199. fn=update_history_tab,
  200. inputs=[directory_dropdown],
  201. # outputs=[history_list, history_list_as_gallery],
  202. outputs=[history_list],
  203. )
  204. reload_button.click(
  205. fn=lambda x: gr.Dataframe(value=get_wav_files(x)),
  206. inputs=[directory_dropdown],
  207. outputs=[history_list],
  208. api_name=f"{'collections' if show_collections else directory}_refresh_history",
  209. )
  210. def save_to_collection_ui(
  211. directory: str,
  212. directories: list[str],
  213. folder_root: gr.Textbox,
  214. directories_state: gr.JSON,
  215. ):
  216. with gr.Row():
  217. move_to_collection = gr.Dropdown(
  218. label="Save to collection",
  219. choices=directories,
  220. value=directory,
  221. )
  222. move_to_collection.select(
  223. fn=save_to_collection,
  224. inputs=[folder_root, move_to_collection],
  225. outputs=[move_to_collection],
  226. )
  227. directories_state.change(
  228. fn=lambda x: gr.Dropdown(choices=x),
  229. inputs=[directories_state],
  230. outputs=[move_to_collection],
  231. )
  232. def create_collection_ui(directories_state):
  233. new_collection_name = gr.Textbox(label="New collection name", value="")
  234. def create_collection(new_collection_name):
  235. os.makedirs(os.path.join("collections", new_collection_name))
  236. return [
  237. get_collections(),
  238. gr.Button(value="Created"),
  239. ]
  240. create_collection_button = gr.Button(value="Create collection")
  241. new_collection_name.change(
  242. fn=lambda: gr.Button(value="Create collection"),
  243. outputs=[create_collection_button],
  244. )
  245. create_collection_button.click(
  246. fn=create_collection,
  247. inputs=[new_collection_name],
  248. outputs=[directories_state, create_collection_button],
  249. )