output.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import json
  2. import logging
  3. from collections.abc import Mapping
  4. from .framework import Global, Task
  5. from .input_ctrl import send_msg, single_input, input_control, next_event, run_async
  6. import asyncio
  7. import inspect
  8. def set_title(title):
  9. send_msg('output_ctl', dict(title=title))
  10. def text_print(text, *, ws=None):
  11. if text is None:
  12. text = ''
  13. msg = dict(command="output", spec=dict(content=text, type='text'))
  14. (ws or Global.active_ws).write_message(json.dumps(msg))
  15. def json_print(obj):
  16. text = "```\n%s\n```" % json.dumps(obj, indent=4, ensure_ascii=False)
  17. text_print(text)
  18. put_markdown = text_print
  19. def put_table(tdata):
  20. """
  21. | \| | | |
  22. | ---- | ---- | ---- | ---- |
  23. | | | | |
  24. | | | | |
  25. | | | | |
  26. :param tdata:
  27. :return:
  28. """
  29. def quote(data):
  30. return data.replace('|', r'\|')
  31. header = "|%s|" % "|".join(map(quote, tdata[0]))
  32. res = [header]
  33. res.append("|%s|" % "|".join(['----'] * len(tdata[0])))
  34. for tr in tdata[1:]:
  35. t = "|%s|" % "|".join(map(quote, tr))
  36. res.append(t)
  37. text_print('\n'.join(res))
  38. def buttons(buttons, onclick_coro, save=None, mutex_mode=False):
  39. """
  40. :param buttons: button列表, button可用形式:
  41. {value:, label:, }
  42. (value, label,)
  43. value 单值,label等于value
  44. :param onclick_coro: CallBack(data, save) todo 允许onclick_coro非coro
  45. :param save:
  46. :param mutex_mode: 互斥模式,回调在运行过程中,无法响应同一回调
  47. :return:
  48. """
  49. btns = []
  50. for btn in buttons:
  51. if isinstance(btn, Mapping):
  52. assert 'value' in btn and 'label' in btn, 'actions item must have value and label key'
  53. elif isinstance(btn, list):
  54. assert len(btn) == 2, 'actions item format error'
  55. btn = dict(zip(('value', 'label'), btn))
  56. else:
  57. btn = dict(value=btn, label=btn)
  58. btns.append(btn)
  59. async def callback_coro():
  60. while True:
  61. event = await next_event()
  62. assert event['event'] == 'callback'
  63. coro = None
  64. if asyncio.iscoroutinefunction(onclick_coro):
  65. coro = onclick_coro(event['data'], save)
  66. elif inspect.isgeneratorfunction(onclick_coro):
  67. coro = asyncio.coroutine(onclick_coro)(save, event['data'])
  68. else:
  69. onclick_coro(event['data'], save)
  70. if coro is not None:
  71. if mutex_mode:
  72. await coro
  73. else:
  74. run_async(coro)
  75. print('Global.active_ws', Global.active_ws)
  76. callback = Task(callback_coro(), Global.active_ws)
  77. callback.coro.send(None) # 激活,Non't callback.step() ,导致嵌套调用step todo 与inactive_coro_instances整合
  78. # callback_id = callback.coro_id
  79. Global.active_ws.coros[callback.coro_id] = callback
  80. send_msg('output', dict(type='buttons', callback_id=callback.coro_id, buttons=btns))