Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. # encoding:utf-8
  2. import json
  3. import os
  4. from bridge.context import ContextType
  5. from bridge.reply import Reply, ReplyType
  6. from config import conf
  7. import plugins
  8. from plugins import *
  9. from common.log import logger
  10. import webuiapi
  11. import io
  12. @plugins.register(name="sdwebui", desc="利用stable-diffusion webui来画图", version="2.0", author="lanvent")
  13. class SDWebUI(Plugin):
  14. def __init__(self):
  15. super().__init__()
  16. curdir = os.path.dirname(__file__)
  17. config_path = os.path.join(curdir, "config.json")
  18. try:
  19. with open(config_path, "r", encoding="utf-8") as f:
  20. config = json.load(f)
  21. self.rules = config["rules"]
  22. defaults = config["defaults"]
  23. self.default_params = defaults["params"]
  24. self.default_options = defaults["options"]
  25. self.start_args = config["start"]
  26. self.api = webuiapi.WebUIApi(**self.start_args)
  27. self.handlers[Event.ON_HANDLE_CONTEXT] = self.on_handle_context
  28. logger.info("[SD] inited")
  29. except Exception as e:
  30. if isinstance(e, FileNotFoundError):
  31. logger.warn(f"[SD] init failed, {config_path} not found, ignore or see https://github.com/zhayujie/chatgpt-on-wechat/tree/master/plugins/sdwebui .")
  32. else:
  33. logger.warn("[SD] init failed, ignore or see https://github.com/zhayujie/chatgpt-on-wechat/tree/master/plugins/sdwebui .")
  34. raise e
  35. def on_handle_context(self, e_context: EventContext):
  36. if e_context['context'].type != ContextType.IMAGE_CREATE:
  37. return
  38. logger.debug("[SD] on_handle_context. content: %s" %e_context['context'].content)
  39. logger.info("[SD] image_query={}".format(e_context['context'].content))
  40. reply = Reply()
  41. try:
  42. content = e_context['context'].content[:]
  43. # 解析用户输入 如"横版 高清 二次元:cat"
  44. if ":" in content:
  45. keywords, prompt = content.split(":", 1)
  46. else:
  47. keywords = content
  48. prompt = ""
  49. keywords = keywords.split()
  50. if "help" in keywords or "帮助" in keywords:
  51. reply.type = ReplyType.INFO
  52. reply.content = self.get_help_text(verbose = True)
  53. else:
  54. rule_params = {}
  55. rule_options = {}
  56. for keyword in keywords:
  57. matched = False
  58. for rule in self.rules:
  59. if keyword in rule["keywords"]:
  60. for key in rule["params"]:
  61. rule_params[key] = rule["params"][key]
  62. if "options" in rule:
  63. for key in rule["options"]:
  64. rule_options[key] = rule["options"][key]
  65. matched = True
  66. break # 一个关键词只匹配一个规则
  67. if not matched:
  68. logger.warning("[SD] keyword not matched: %s" % keyword)
  69. params = {**self.default_params, **rule_params}
  70. options = {**self.default_options, **rule_options}
  71. params["prompt"] = params.get("prompt", "")+f", {prompt}"
  72. if len(options) > 0:
  73. logger.info("[SD] cover options={}".format(options))
  74. self.api.set_options(options)
  75. logger.info("[SD] params={}".format(params))
  76. result = self.api.txt2img(
  77. **params
  78. )
  79. reply.type = ReplyType.IMAGE
  80. b_img = io.BytesIO()
  81. result.image.save(b_img, format="PNG")
  82. reply.content = b_img
  83. e_context.action = EventAction.BREAK_PASS # 事件结束后,跳过处理context的默认逻辑
  84. except Exception as e:
  85. reply.type = ReplyType.ERROR
  86. reply.content = "[SD] "+str(e)
  87. logger.error("[SD] exception: %s" % e)
  88. e_context.action = EventAction.CONTINUE # 事件继续,交付给下个插件或默认逻辑
  89. finally:
  90. e_context['reply'] = reply
  91. def get_help_text(self, verbose = False, **kwargs):
  92. if not conf().get('image_create_prefix'):
  93. return "画图功能未启用"
  94. else:
  95. trigger = conf()['image_create_prefix'][0]
  96. help_text = "利用stable-diffusion来画图。\n"
  97. if not verbose:
  98. return help_text
  99. help_text += f"使用方法:\n使用\"{trigger}[关键词1] [关键词2]...:提示语\"的格式作画,如\"{trigger}横版 高清:cat\"\n"
  100. help_text += "目前可用关键词:\n"
  101. for rule in self.rules:
  102. keywords = [f"[{keyword}]" for keyword in rule['keywords']]
  103. help_text += f"{','.join(keywords)}"
  104. if "desc" in rule:
  105. help_text += f"-{rule['desc']}\n"
  106. else:
  107. help_text += "\n"
  108. return help_text