ui_extra_networks_user_metadata.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. import datetime
  2. import html
  3. import json
  4. import os.path
  5. import gradio as gr
  6. from modules import generation_parameters_copypaste, images, sysinfo, errors
  7. class UserMetadataEditor:
  8. def __init__(self, ui, tabname, page):
  9. self.ui = ui
  10. self.tabname = tabname
  11. self.page = page
  12. self.id_part = f"{self.tabname}_{self.page.id_page}_edit_user_metadata"
  13. self.box = None
  14. self.edit_name_input = None
  15. self.button_edit = None
  16. self.edit_name = None
  17. self.edit_description = None
  18. self.edit_notes = None
  19. self.html_filedata = None
  20. self.html_preview = None
  21. self.html_status = None
  22. self.button_cancel = None
  23. self.button_replace_preview = None
  24. self.button_save = None
  25. def get_user_metadata(self, name):
  26. item = self.page.items.get(name, {})
  27. user_metadata = item.get('user_metadata', None)
  28. if user_metadata is None:
  29. user_metadata = {}
  30. item['user_metadata'] = user_metadata
  31. return user_metadata
  32. def create_extra_default_items_in_left_column(self):
  33. pass
  34. def create_default_editor_elems(self):
  35. with gr.Row():
  36. with gr.Column(scale=2):
  37. self.edit_name = gr.HTML(elem_classes="extra-network-name")
  38. self.edit_description = gr.Textbox(label="Description", lines=4)
  39. self.html_filedata = gr.HTML()
  40. self.create_extra_default_items_in_left_column()
  41. with gr.Column(scale=1, min_width=0):
  42. self.html_preview = gr.HTML()
  43. def create_default_buttons(self):
  44. with gr.Row(elem_classes="edit-user-metadata-buttons"):
  45. self.button_cancel = gr.Button('Cancel')
  46. self.button_replace_preview = gr.Button('Replace preview', variant='primary')
  47. self.button_save = gr.Button('Save', variant='primary')
  48. self.html_status = gr.HTML(elem_classes="edit-user-metadata-status")
  49. self.button_cancel.click(fn=None, _js="closePopup")
  50. def get_card_html(self, name):
  51. item = self.page.items.get(name, {})
  52. preview_url = item.get("preview", None)
  53. if not preview_url:
  54. filename, _ = os.path.splitext(item["filename"])
  55. preview_url = self.page.find_preview(filename)
  56. item["preview"] = preview_url
  57. if preview_url:
  58. preview = f'''
  59. <div class='card standalone-card-preview'>
  60. <img src="{html.escape(preview_url)}" class="preview">
  61. </div>
  62. '''
  63. else:
  64. preview = "<div class='card standalone-card-preview'></div>"
  65. return preview
  66. def get_metadata_table(self, name):
  67. item = self.page.items.get(name, {})
  68. try:
  69. filename = item["filename"]
  70. stats = os.stat(filename)
  71. params = [
  72. ('File size: ', sysinfo.pretty_bytes(stats.st_size)),
  73. ('Modified: ', datetime.datetime.fromtimestamp(stats.st_mtime).strftime('%Y-%m-%d %H:%M')),
  74. ]
  75. return params
  76. except Exception as e:
  77. errors.display(e, f"reading info for {name}")
  78. return []
  79. def put_values_into_components(self, name):
  80. user_metadata = self.get_user_metadata(name)
  81. try:
  82. params = self.get_metadata_table(name)
  83. except Exception as e:
  84. errors.display(e, f"reading metadata info for {name}")
  85. params = []
  86. table = '<table class="file-metadata">' + "".join(f"<tr><th>{name}</th><td>{value}</td></tr>" for name, value in params) + '</table>'
  87. return html.escape(name), user_metadata.get('description', ''), table, self.get_card_html(name), user_metadata.get('notes', '')
  88. def write_user_metadata(self, name, metadata):
  89. item = self.page.items.get(name, {})
  90. filename = item.get("filename", None)
  91. basename, ext = os.path.splitext(filename)
  92. with open(basename + '.json', "w", encoding="utf8") as file:
  93. json.dump(metadata, file)
  94. def save_user_metadata(self, name, desc, notes):
  95. user_metadata = self.get_user_metadata(name)
  96. user_metadata["description"] = desc
  97. user_metadata["notes"] = notes
  98. self.write_user_metadata(name, user_metadata)
  99. def setup_save_handler(self, button, func, components):
  100. button\
  101. .click(fn=func, inputs=[self.edit_name_input, *components], outputs=[])\
  102. .then(fn=None, _js="function(name){closePopup(); extraNetworksRefreshSingleCard(" + json.dumps(self.page.name) + "," + json.dumps(self.tabname) + ", name);}", inputs=[self.edit_name_input], outputs=[])
  103. def create_editor(self):
  104. self.create_default_editor_elems()
  105. self.edit_notes = gr.TextArea(label='Notes', lines=4)
  106. self.create_default_buttons()
  107. self.button_edit\
  108. .click(fn=self.put_values_into_components, inputs=[self.edit_name_input], outputs=[self.edit_name, self.edit_description, self.html_filedata, self.html_preview, self.edit_notes])\
  109. .then(fn=lambda: gr.update(visible=True), inputs=[], outputs=[self.box])
  110. self.setup_save_handler(self.button_save, self.save_user_metadata, [self.edit_description, self.edit_notes])
  111. def create_ui(self):
  112. with gr.Box(visible=False, elem_id=self.id_part, elem_classes="edit-user-metadata") as box:
  113. self.box = box
  114. self.edit_name_input = gr.Textbox("Edit user metadata card id", visible=False, elem_id=f"{self.id_part}_name")
  115. self.button_edit = gr.Button("Edit user metadata", visible=False, elem_id=f"{self.id_part}_button")
  116. self.create_editor()
  117. def save_preview(self, index, gallery, name):
  118. if len(gallery) == 0:
  119. return self.get_card_html(name), "There is no image in gallery to save as a preview."
  120. item = self.page.items.get(name, {})
  121. index = int(index)
  122. index = 0 if index < 0 else index
  123. index = len(gallery) - 1 if index >= len(gallery) else index
  124. img_info = gallery[index if index >= 0 else 0]
  125. image = generation_parameters_copypaste.image_from_url_text(img_info)
  126. geninfo, items = images.read_info_from_image(image)
  127. images.save_image_with_geninfo(image, geninfo, item["local_preview"])
  128. return self.get_card_html(name), ''
  129. def setup_ui(self, gallery):
  130. self.button_replace_preview.click(
  131. fn=self.save_preview,
  132. _js="function(x, y, z){return [selected_gallery_index(), y, z]}",
  133. inputs=[self.edit_name_input, gallery, self.edit_name_input],
  134. outputs=[self.html_preview, self.html_status]
  135. ).then(
  136. fn=None,
  137. _js="function(name){extraNetworksRefreshSingleCard(" + json.dumps(self.page.name) + "," + json.dumps(self.tabname) + ", name);}",
  138. inputs=[self.edit_name_input],
  139. outputs=[]
  140. )