exit-note-and-preview.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #!/usr/bin/env python3
  2. """退出笔记:点击「业务合作」,再调用 ``preview-note`` 生成预览 HTML。"""
  3. from __future__ import annotations
  4. import sys
  5. import time
  6. from pathlib import Path
  7. from playwright.sync_api import Page
  8. _REPOSITORY_ROOT_DIRECTORY = Path(__file__).resolve().parent.parent.parent
  9. if str(_REPOSITORY_ROOT_DIRECTORY) not in sys.path:
  10. sys.path.insert(0, str(_REPOSITORY_ROOT_DIRECTORY))
  11. from workplace import playwright as workplace_playwright # noqa: E402
  12. from workplace import pyautogui as workplace_pyautogui # noqa: E402
  13. from workplace.download_note_shared import ( # noqa: E402
  14. BUSINESS_COOPERATION_BUTTON_VISIBLE_TEXT_FOR_OCR_ANCHOR,
  15. PROJECT_CONFIG_BUSINESS_COOPERATION_BTN_SCREEN_XY_PAIR_CONFIG_KEY,
  16. REPOSITORY_ROOT_DIRECTORY,
  17. load_python_module_from_file,
  18. )
  19. from workplace.note_pipeline_forbidden_standalone_url_image_fetch import (
  20. XHS_NOTE_PIPELINE_ABSOLUTE_PROHIBITION_STANDALONE_HTTP_GET_FOR_IMAGE_BYTES,
  21. )
  22. from workplace.screenshot import capture_full_screen_screenshot_bgr_numpy_and_save_screenshot_png # noqa: E402
  23. from workplace.singleton import HOME_PAGE_URL, REPOSITORY_CONFIG_INI_SNAPSHOT # noqa: E402
  24. DEFAULT_NOTE_LIST_ZERO_BASED_INDEX_STRING = "0"
  25. def _load_open_browser_module():
  26. return load_python_module_from_file(
  27. REPOSITORY_ROOT_DIRECTORY / "workplace" / "open-browser.py",
  28. "workplace_open_browser_exit_note",
  29. )
  30. def _load_move_mouse_to_pos_module():
  31. return load_python_module_from_file(
  32. REPOSITORY_ROOT_DIRECTORY / "workplace" / "move-mouse-to-pos.py",
  33. "workplace_move_mouse_to_pos_exit_note",
  34. )
  35. def _load_ocr_pos_module():
  36. return load_python_module_from_file(
  37. REPOSITORY_ROOT_DIRECTORY / "workplace" / "ocr-pos.py",
  38. "workplace_ocr_pos_exit_note",
  39. )
  40. def _load_config_save_read_module():
  41. return load_python_module_from_file(
  42. REPOSITORY_ROOT_DIRECTORY / "workplace" / "config-save-read.py",
  43. "workplace_config_save_read_exit_note",
  44. )
  45. def _load_preview_note_module():
  46. return load_python_module_from_file(
  47. REPOSITORY_ROOT_DIRECTORY / "workplace" / "preview-note" / "preview-note.py",
  48. "workplace_preview_note_exit_note",
  49. )
  50. def start(
  51. command_line_argument_strings: list[str] | None = None,
  52. *,
  53. existing_playwright_page: Page | None = None,
  54. cached_image_body_by_request_url: dict[str, bytes] | None = None,
  55. ) -> int:
  56. _ = XHS_NOTE_PIPELINE_ABSOLUTE_PROHIBITION_STANDALONE_HTTP_GET_FOR_IMAGE_BYTES
  57. _ = cached_image_body_by_request_url
  58. command_line_arguments = (
  59. command_line_argument_strings
  60. if command_line_argument_strings is not None
  61. else sys.argv[1:]
  62. )
  63. note_list_position_zero_based_index_string = (
  64. command_line_arguments[0]
  65. if command_line_arguments
  66. else DEFAULT_NOTE_LIST_ZERO_BASED_INDEX_STRING
  67. )
  68. workplace_pyautogui.init_singleton()
  69. workplace_playwright.init_singleton()
  70. move_mouse_to_pos_script_module = _load_move_mouse_to_pos_module()
  71. ocr_pos_script_module = _load_ocr_pos_module()
  72. config_save_read_script_module = _load_config_save_read_module()
  73. preview_note_script_module = _load_preview_note_module()
  74. def _run_using_playwright_page(playwright_page_for_search_results: Page) -> int:
  75. note_detail_playwright_page = playwright_page_for_search_results
  76. note_detail_playwright_page.bring_to_front()
  77. project_config_dictionary = REPOSITORY_CONFIG_INI_SNAPSHOT.project_config
  78. business_cooperation_button_screen_xy_integer_pair = (
  79. config_save_read_script_module.input_keyword_xy_pair_from_config(
  80. project_config_dictionary,
  81. PROJECT_CONFIG_BUSINESS_COOPERATION_BTN_SCREEN_XY_PAIR_CONFIG_KEY,
  82. )
  83. )
  84. if business_cooperation_button_screen_xy_integer_pair is None:
  85. full_screen_screenshot_bgr_numpy_for_business_cooperation_button = (
  86. capture_full_screen_screenshot_bgr_numpy_and_save_screenshot_png()
  87. )
  88. business_cooperation_label_center_screen_xy_integer_pair = (
  89. ocr_pos_script_module.ocr_find_text_center(
  90. full_screen_screenshot_bgr_numpy_for_business_cooperation_button,
  91. BUSINESS_COOPERATION_BUTTON_VISIBLE_TEXT_FOR_OCR_ANCHOR,
  92. )
  93. )
  94. if business_cooperation_label_center_screen_xy_integer_pair is None:
  95. raise RuntimeError(
  96. "OCR did not find on-screen anchor text: "
  97. f"{BUSINESS_COOPERATION_BUTTON_VISIBLE_TEXT_FOR_OCR_ANCHOR!r}",
  98. )
  99. business_cooperation_button_screen_xy_integer_pair = (
  100. int(business_cooperation_label_center_screen_xy_integer_pair[0]),
  101. int(business_cooperation_label_center_screen_xy_integer_pair[1]),
  102. )
  103. config_save_read_script_module.merge_input_keyword_config(
  104. business_cooperation_btn_pos=business_cooperation_button_screen_xy_integer_pair,
  105. )
  106. business_cooperation_click_screen_x = int(
  107. business_cooperation_button_screen_xy_integer_pair[0],
  108. )
  109. business_cooperation_click_screen_y = int(
  110. business_cooperation_button_screen_xy_integer_pair[1],
  111. )
  112. move_mouse_to_pos_script_module.start(
  113. business_cooperation_click_screen_x,
  114. business_cooperation_click_screen_y,
  115. )
  116. time.sleep(0.35)
  117. workplace_pyautogui.click_here()
  118. return preview_note_script_module.start(
  119. [note_list_position_zero_based_index_string],
  120. )
  121. if existing_playwright_page is not None:
  122. return _run_using_playwright_page(existing_playwright_page)
  123. open_browser_script_module = _load_open_browser_module()
  124. with workplace_playwright.sync_playwright_singleton() as playwright_sync_driver:
  125. first_step_exit_code, playwright_page = (
  126. open_browser_script_module.prepare_page_at_home_url(
  127. playwright_sync_driver,
  128. HOME_PAGE_URL,
  129. cdp=None,
  130. )
  131. )
  132. if first_step_exit_code != 0:
  133. return first_step_exit_code
  134. if playwright_page is None:
  135. return 1
  136. return _run_using_playwright_page(playwright_page)
  137. def main() -> int:
  138. return start()
  139. __all__ = ["DEFAULT_NOTE_LIST_ZERO_BASED_INDEX_STRING", "start", "main"]
  140. if __name__ == "__main__":
  141. raise SystemExit(main())