選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
 
 

144 行
3.5 KiB

  1. # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
  2. # License: MIT. See LICENSE
  3. import os
  4. import redis
  5. import frappe
  6. from frappe.utils.data import cstr
  7. redis_server = None
  8. def publish_progress(percent, title=None, doctype=None, docname=None, description=None):
  9. publish_realtime(
  10. "progress",
  11. {"percent": percent, "title": title, "description": description},
  12. user=frappe.session.user,
  13. doctype=doctype,
  14. docname=docname,
  15. )
  16. def publish_realtime(
  17. event=None,
  18. message=None,
  19. room=None,
  20. user=None,
  21. doctype=None,
  22. docname=None,
  23. task_id=None,
  24. after_commit=False,
  25. ):
  26. """Publish real-time updates
  27. :param event: Event name, like `task_progress` etc. that will be handled by the client (default is `task_progress` if within task or `global`)
  28. :param message: JSON message object. For async must contain `task_id`
  29. :param room: Room in which to publish update (default entire site)
  30. :param user: Transmit to user
  31. :param doctype: Transmit to doctype, docname
  32. :param docname: Transmit to doctype, docname
  33. :param after_commit: (default False) will emit after current transaction is committed"""
  34. if message is None:
  35. message = {}
  36. if event is None:
  37. if getattr(frappe.local, "task_id", None):
  38. event = "task_progress"
  39. else:
  40. event = "global"
  41. if event == "msgprint" and not user:
  42. user = frappe.session.user
  43. if not room:
  44. if not task_id and hasattr(frappe.local, "task_id"):
  45. task_id = frappe.local.task_id
  46. if task_id:
  47. room = get_task_progress_room(task_id)
  48. if not "task_id" in message:
  49. message["task_id"] = task_id
  50. after_commit = False
  51. elif user:
  52. room = get_user_room(user)
  53. elif doctype and docname:
  54. room = get_doc_room(doctype, docname)
  55. else:
  56. room = get_site_room()
  57. if after_commit:
  58. params = [event, message, room]
  59. if params not in frappe.local.realtime_log:
  60. frappe.local.realtime_log.append(params)
  61. else:
  62. emit_via_redis(event, message, room)
  63. def emit_via_redis(event, message, room):
  64. """Publish real-time updates via redis
  65. :param event: Event name, like `task_progress` etc.
  66. :param message: JSON message object. For async must contain `task_id`
  67. :param room: name of the room"""
  68. r = get_redis_server()
  69. try:
  70. r.publish("events", frappe.as_json({"event": event, "message": message, "room": room}))
  71. except redis.exceptions.ConnectionError:
  72. # print(frappe.get_traceback())
  73. pass
  74. def get_redis_server():
  75. """returns redis_socketio connection."""
  76. global redis_server
  77. if not redis_server:
  78. from redis import Redis
  79. redis_server = Redis.from_url(frappe.conf.redis_socketio or "redis://localhost:12311")
  80. return redis_server
  81. @frappe.whitelist(allow_guest=True)
  82. def can_subscribe_doc(doctype, docname):
  83. if os.environ.get("CI"):
  84. return True
  85. from frappe.exceptions import PermissionError
  86. from frappe.sessions import Session
  87. session = Session(None, resume=True).get_session_data()
  88. if not frappe.has_permission(user=session.user, doctype=doctype, doc=docname, ptype="read"):
  89. raise PermissionError()
  90. return True
  91. @frappe.whitelist(allow_guest=True)
  92. def get_user_info():
  93. from frappe.sessions import Session
  94. session = Session(None, resume=True).get_session_data()
  95. return {
  96. "user": session.user,
  97. }
  98. def get_doc_room(doctype, docname):
  99. return "".join([frappe.local.site, ":doc:", doctype, "/", cstr(docname)])
  100. def get_user_room(user):
  101. return "".join([frappe.local.site, ":user:", user])
  102. def get_site_room():
  103. return "".join([frappe.local.site, ":all"])
  104. def get_task_progress_room(task_id):
  105. return "".join([frappe.local.site, ":task_progress:", task_id])