@whyour/qinglong 0.11.2 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/README-en.md +65 -58
  2. package/README.md +62 -55
  3. package/package.json +2 -2
  4. package/sample/config.sample.sh +9 -0
  5. package/sample/notify.js +260 -0
  6. package/sample/notify.py +177 -3
  7. package/shell/otask.sh +8 -6
  8. package/shell/share.sh +20 -11
  9. package/shell/task.sh +21 -5
  10. package/static/build/api/cron.js +1 -2
  11. package/static/build/api/log.js +1 -1
  12. package/static/build/api/script.js +4 -3
  13. package/static/build/config/serverEnv.js +8 -0
  14. package/static/build/config/util.js +13 -7
  15. package/static/build/data/notify.js +11 -1
  16. package/static/build/loaders/server.js +0 -4
  17. package/static/build/protos/cron.js +14 -2
  18. package/static/build/schedule/addCron.js +5 -5
  19. package/static/build/services/cron.js +20 -13
  20. package/static/build/services/dependence.js +1 -1
  21. package/static/build/services/notify.js +57 -5
  22. package/static/build/services/schedule.js +23 -11
  23. package/static/build/services/script.js +1 -1
  24. package/static/build/services/subscription.js +5 -1
  25. package/static/build/services/system.js +3 -1
  26. package/static/build/shared/pLimit.js +38 -18
  27. package/static/build/shared/runCron.js +5 -6
  28. package/static/dist/{7878.91f5096f.async.js → 1988.5291d10f.async.js} +1 -1
  29. package/static/dist/2260.6c4d0bd0.async.js +1 -0
  30. package/static/dist/2393.c35a1174.async.js +1 -0
  31. package/static/dist/{2618.d4ab1f05.async.js → 2618.7a71aedf.async.js} +1 -1
  32. package/static/dist/{2715.f6d4a9ed.async.js → 2715.292538bc.async.js} +1 -1
  33. package/static/dist/{29.dd4d8489.async.js → 29.32a92099.async.js} +1 -1
  34. package/static/dist/3435.2670d41f.async.js +1 -0
  35. package/static/dist/380.33bc8989.async.js +1 -0
  36. package/static/dist/3800.f0507af4.async.js +1 -0
  37. package/static/dist/{4124.27cef0bd.async.js → 4124.b86154ed.async.js} +1 -1
  38. package/static/dist/4163.1781a549.async.js +1 -0
  39. package/static/dist/419.e21ea0bd.async.js +1 -0
  40. package/static/dist/4378.59be202f.async.js +1 -0
  41. package/static/dist/4424.a840b858.async.js +1 -0
  42. package/static/dist/4674.1b3db685.async.js +1 -0
  43. package/static/dist/{4925.9e8a41a2.async.js → 4925.9b770864.async.js} +1 -1
  44. package/static/dist/5310.4cd7a0c1.async.js +1 -0
  45. package/static/dist/{5484.8b81227f.async.js → 5484.68655765.async.js} +1 -1
  46. package/static/dist/5619.db04f386.async.js +1 -0
  47. package/static/dist/5830.9be47cbb.async.js +1 -0
  48. package/static/dist/6644.1f11b8fa.async.js +1 -0
  49. package/static/dist/694.0baa21db.async.js +1 -0
  50. package/static/dist/6986.6a4ae181.async.js +1 -0
  51. package/static/dist/{7382.26e7f5a4.async.js → 7346.7096e3b3.async.js} +1 -1
  52. package/static/dist/{7362.9fde9d80.async.js → 7362.e740709d.async.js} +1 -1
  53. package/static/dist/7393.341d9643.async.js +1 -0
  54. package/static/dist/{7708.dc75b315.async.js → 7708.27674f3a.async.js} +1 -1
  55. package/static/dist/7742.51617038.async.js +1 -0
  56. package/static/dist/7787.2fcf966f.async.js +1 -0
  57. package/static/dist/8008.cf4ff203.async.js +1 -0
  58. package/static/dist/8171.e2986b87.async.js +1 -0
  59. package/static/dist/8297.0c80e09a.async.js +1 -0
  60. package/static/dist/833.5add31bf.async.js +1 -0
  61. package/static/dist/{8432.055570e6.async.js → 8432.d8d0ade6.async.js} +1 -1
  62. package/static/dist/858.1a385b25.async.js +1 -0
  63. package/static/dist/8934.55adca8f.async.js +1 -0
  64. package/static/dist/{9065.8be8d60f.async.js → 9065.a1341834.async.js} +1 -1
  65. package/static/dist/9206.25353766.async.js +1 -0
  66. package/static/dist/{9504.248f6493.async.js → 9504.22415050.async.js} +1 -1
  67. package/static/dist/9525.b2007159.async.js +1 -0
  68. package/static/dist/9673.ac17e45d.async.js +1 -0
  69. package/static/dist/index.html +1 -1
  70. package/static/dist/layouts__index.308c5e5e.chunk.css +1 -0
  71. package/static/dist/layouts__index.931ce4c3.async.js +1 -0
  72. package/static/dist/{src__pages__404.e6b13931.async.js → src__pages__404.e1ca45fd.async.js} +1 -1
  73. package/static/dist/src__pages__config__index.9d83dfb7.async.js +1 -0
  74. package/static/dist/src__pages__crontab__detail.b91d6518.async.js +1 -0
  75. package/static/dist/src__pages__crontab__index.04176975.async.js +1 -0
  76. package/static/dist/src__pages__crontab__index.b622c4d6.chunk.css +1 -0
  77. package/static/dist/src__pages__crontab__logModal.91357c7c.async.js +1 -0
  78. package/static/dist/src__pages__crontab__modal.3fa8f075.async.js +1 -0
  79. package/static/dist/{src__pages__crontab__viewCreateModal.c46df55e.async.js → src__pages__crontab__viewCreateModal.a29322e7.async.js} +1 -1
  80. package/static/dist/{src__pages__crontab__viewManageModal.67aa809d.async.js → src__pages__crontab__viewManageModal.c026d403.async.js} +1 -1
  81. package/static/dist/{src__pages__dependence__index.1908bb39.async.js → src__pages__dependence__index.21153c24.async.js} +1 -1
  82. package/static/dist/src__pages__dependence__logModal.5aada63c.async.js +1 -0
  83. package/static/dist/src__pages__dependence__modal.96353c88.async.js +1 -0
  84. package/static/dist/src__pages__diff__index.e644b15f.async.js +1 -0
  85. package/static/dist/src__pages__env__editNameModal.25c21e59.async.js +1 -0
  86. package/static/dist/src__pages__env__index.f545d035.async.js +1 -0
  87. package/static/dist/src__pages__env__modal.4fd6abc2.async.js +1 -0
  88. package/static/dist/src__pages__error__index.f3ca5563.async.js +1 -0
  89. package/static/dist/src__pages__initialization__index.727e0f70.async.js +1 -0
  90. package/static/dist/{src__pages__log__index.4010410c.async.js → src__pages__log__index.ba2c1721.async.js} +1 -1
  91. package/static/dist/src__pages__login__index.e4257741.async.js +1 -0
  92. package/static/dist/src__pages__script__editModal.8d7bac2a.async.js +1 -0
  93. package/static/dist/src__pages__script__editNameModal.ca76e055.async.js +1 -0
  94. package/static/dist/src__pages__script__index.da31e2c2.async.js +1 -0
  95. package/static/dist/src__pages__script__renameModal.c166915b.async.js +1 -0
  96. package/static/dist/src__pages__script__saveModal.7ee07566.async.js +1 -0
  97. package/static/dist/src__pages__script__setting.020a7629.async.js +1 -0
  98. package/static/dist/src__pages__setting__about.40dce429.async.js +1 -0
  99. package/static/dist/src__pages__setting__appModal.efa5bb29.async.js +1 -0
  100. package/static/dist/src__pages__setting__checkUpdate.42020a45.async.js +1 -0
  101. package/static/dist/src__pages__setting__index.540c33a4.async.js +1 -0
  102. package/static/dist/src__pages__setting__loginLog.fe7238b5.async.js +1 -0
  103. package/static/dist/src__pages__setting__notification.b99a4c64.async.js +1 -0
  104. package/static/dist/src__pages__setting__other.d20be1c1.async.js +1 -0
  105. package/static/dist/src__pages__setting__progress.65e2e878.async.js +1 -0
  106. package/static/dist/src__pages__setting__security.d14993c7.async.js +1 -0
  107. package/static/dist/src__pages__setting__systemLog.751cc94d.async.js +1 -0
  108. package/static/dist/src__pages__subscription__index.0f0a7c0a.async.js +1 -0
  109. package/static/dist/src__pages__subscription__logModal.fce8a9b4.async.js +1 -0
  110. package/static/dist/src__pages__subscription__modal.61e787ce.async.js +1 -0
  111. package/static/dist/umi.0397b91d.js +1 -0
  112. package/version.yaml +17 -10
  113. package/static/dist/1124.0d983222.async.js +0 -1
  114. package/static/dist/2260.6b2b0020.async.js +0 -1
  115. package/static/dist/2393.4404a4fc.async.js +0 -1
  116. package/static/dist/2536.282cde37.async.js +0 -1
  117. package/static/dist/3271.e5502cf4.async.js +0 -1
  118. package/static/dist/3435.4a54080b.async.js +0 -1
  119. package/static/dist/380.1bd1f124.async.js +0 -1
  120. package/static/dist/3800.fca63cfc.async.js +0 -1
  121. package/static/dist/4163.2fc47c9d.async.js +0 -1
  122. package/static/dist/419.f84c4548.async.js +0 -1
  123. package/static/dist/4424.73f63db5.async.js +0 -1
  124. package/static/dist/4674.0196afcf.async.js +0 -1
  125. package/static/dist/5310.213fe20f.async.js +0 -1
  126. package/static/dist/6433.d9698b6c.async.js +0 -1
  127. package/static/dist/6644.fe01612c.async.js +0 -1
  128. package/static/dist/6805.5446eb5a.async.js +0 -1
  129. package/static/dist/6986.57a091e1.async.js +0 -1
  130. package/static/dist/7393.1f1df786.async.js +0 -1
  131. package/static/dist/7742.863081f5.async.js +0 -1
  132. package/static/dist/8008.882bf214.async.js +0 -1
  133. package/static/dist/8037.dd53e9c8.async.js +0 -1
  134. package/static/dist/8297.c44afb18.async.js +0 -1
  135. package/static/dist/833.ca85f497.async.js +0 -1
  136. package/static/dist/858.1899883e.async.js +0 -1
  137. package/static/dist/9673.5576fcd4.async.js +0 -1
  138. package/static/dist/9692.e04f774e.async.js +0 -1
  139. package/static/dist/layouts__index.0909c66d.chunk.css +0 -1
  140. package/static/dist/layouts__index.ed595716.async.js +0 -1
  141. package/static/dist/src__pages__config__index.f41a22d4.async.js +0 -1
  142. package/static/dist/src__pages__crontab__detail.b4fc2995.async.js +0 -1
  143. package/static/dist/src__pages__crontab__index.6c7b7b2c.chunk.css +0 -1
  144. package/static/dist/src__pages__crontab__index.776dba58.async.js +0 -1
  145. package/static/dist/src__pages__crontab__logModal.0fb6d62d.async.js +0 -1
  146. package/static/dist/src__pages__crontab__modal.0b01490c.async.js +0 -1
  147. package/static/dist/src__pages__dependence__logModal.8ecc9316.async.js +0 -1
  148. package/static/dist/src__pages__dependence__modal.9c12e6bb.async.js +0 -1
  149. package/static/dist/src__pages__diff__index.e23d088b.async.js +0 -1
  150. package/static/dist/src__pages__env__editNameModal.6f1edde6.async.js +0 -1
  151. package/static/dist/src__pages__env__index.3b08292e.async.js +0 -1
  152. package/static/dist/src__pages__env__modal.ca6133e6.async.js +0 -1
  153. package/static/dist/src__pages__error__index.0b4f4a22.async.js +0 -1
  154. package/static/dist/src__pages__initialization__index.51ebefcb.async.js +0 -1
  155. package/static/dist/src__pages__login__index.8667d8d2.async.js +0 -1
  156. package/static/dist/src__pages__script__editModal.b020a209.async.js +0 -1
  157. package/static/dist/src__pages__script__editNameModal.9220eb1a.async.js +0 -1
  158. package/static/dist/src__pages__script__index.6184a17e.async.js +0 -1
  159. package/static/dist/src__pages__script__renameModal.d6192fed.async.js +0 -1
  160. package/static/dist/src__pages__script__saveModal.eac5e9e7.async.js +0 -1
  161. package/static/dist/src__pages__script__setting.b958297b.async.js +0 -1
  162. package/static/dist/src__pages__setting__about.992010a5.async.js +0 -1
  163. package/static/dist/src__pages__setting__appModal.7563e7b0.async.js +0 -1
  164. package/static/dist/src__pages__setting__checkUpdate.9901a906.async.js +0 -1
  165. package/static/dist/src__pages__setting__index.2aa66013.async.js +0 -1
  166. package/static/dist/src__pages__setting__loginLog.2f2b0a78.async.js +0 -1
  167. package/static/dist/src__pages__setting__notification.e8ce9bdc.async.js +0 -1
  168. package/static/dist/src__pages__setting__other.c6067975.async.js +0 -1
  169. package/static/dist/src__pages__setting__progress.f58bffae.async.js +0 -1
  170. package/static/dist/src__pages__setting__security.cae5c68d.async.js +0 -1
  171. package/static/dist/src__pages__subscription__index.3266194c.async.js +0 -1
  172. package/static/dist/src__pages__subscription__logModal.a023b07e.async.js +0 -1
  173. package/static/dist/src__pages__subscription__modal.49a1a657.async.js +0 -1
  174. package/static/dist/umi.ff82d609.js +0 -1
package/sample/notify.py CHANGED
@@ -101,7 +101,17 @@ push_config = {
101
101
  'SMTP_PASSWORD': '', # SMTP 登录密码,也可能为特殊口令,视具体邮件服务商说明而定
102
102
  'SMTP_NAME': '', # SMTP 收发件人姓名,可随意填写
103
103
 
104
- 'PUSHME_KEY': '', # PushMe 酱的 PUSHME_KEY
104
+ 'PUSHME_KEY': '', # PushMe 酱的 PUSHME_KEY
105
+
106
+ 'CHRONOCAT_QQ': '', # qq号
107
+ 'CHRONOCAT_TOKEN': '', # CHRONOCAT 的token
108
+ 'CHRONOCAT_URL': '', # CHRONOCAT的url地址
109
+
110
+ 'WEBHOOK_URL': '', # 自定义通知 请求地址
111
+ 'WEBHOOK_BODY': '', # 自定义通知 请求体
112
+ 'WEBHOOK_HEADERS': '', # 自定义通知 请求头
113
+ 'WEBHOOK_METHOD': '', # 自定义通知 请求方法
114
+ 'WEBHOOK_CONTENT_TYPE': '' # 自定义通知 content-type
105
115
  }
106
116
  notify_function = []
107
117
  # fmt: on
@@ -446,7 +456,9 @@ class WeCom:
446
456
  return data["access_token"]
447
457
 
448
458
  def send_text(self, message, touser="@all"):
449
- send_url = f"{self.ORIGIN}/cgi-bin/message/send?access_token={self.get_access_token()}"
459
+ send_url = (
460
+ f"{self.ORIGIN}/cgi-bin/message/send?access_token={self.get_access_token()}"
461
+ )
450
462
  send_values = {
451
463
  "touser": touser,
452
464
  "msgtype": "text",
@@ -460,7 +472,9 @@ class WeCom:
460
472
  return respone["errmsg"]
461
473
 
462
474
  def send_mpnews(self, title, message, media_id, touser="@all"):
463
- send_url = f"{self.ORIGIN}/cgi-bin/message/send?access_token={self.get_access_token()}"
475
+ send_url = (
476
+ f"{self.ORIGIN}/cgi-bin/message/send?access_token={self.get_access_token()}"
477
+ )
464
478
  send_values = {
465
479
  "touser": touser,
466
480
  "msgtype": "mpnews",
@@ -643,6 +657,7 @@ def smtp(title: str, content: str) -> None:
643
657
  except Exception as e:
644
658
  print(f"SMTP 邮件 推送失败!{e}")
645
659
 
660
+
646
661
  def pushme(title: str, content: str) -> None:
647
662
  """
648
663
  使用 PushMe 推送消息。
@@ -665,6 +680,157 @@ def pushme(title: str, content: str) -> None:
665
680
  print(f"PushMe 推送失败!{response.status_code} {response.text}")
666
681
 
667
682
 
683
+ def chronocat(title: str, content: str) -> None:
684
+ """
685
+ 使用 CHRONOCAT 推送消息。
686
+ """
687
+ if (
688
+ not push_config.get("CHRONOCAT_URL")
689
+ or not push_config.get("CHRONOCAT_QQ")
690
+ or not push_config.get("CHRONOCAT_TOKEN")
691
+ ):
692
+ print("CHRONOCAT 服务的 CHRONOCAT_URL 或 CHRONOCAT_QQ 未设置!!\n取消推送")
693
+ return
694
+
695
+ print("CHRONOCAT 服务启动")
696
+
697
+ user_ids = re.findall(r"user_id=(\d+)", push_config.get("CHRONOCAT_QQ"))
698
+ group_ids = re.findall(r"group_id=(\d+)", push_config.get("CHRONOCAT_QQ"))
699
+
700
+ url = f'{push_config.get("CHRONOCAT_URL")}/api/message/send'
701
+ headers = {
702
+ "Content-Type": "application/json",
703
+ "Authorization": f'Bearer {push_config.get("CHRONOCAT_TOKEN")}',
704
+ }
705
+
706
+ for chat_type, ids in [(1, user_ids), (2, group_ids)]:
707
+ if not ids:
708
+ continue
709
+ for chat_id in ids:
710
+ data = {
711
+ "peer": {"chatType": chat_type, "peerUin": chat_id},
712
+ "elements": [
713
+ {
714
+ "elementType": 1,
715
+ "textElement": {"content": f"{title}\n\n{content}"},
716
+ }
717
+ ],
718
+ }
719
+ response = requests.post(url, headers=headers, data=json.dumps(data))
720
+ if response.status_code == 200:
721
+ if chat_type == 1:
722
+ print(f"QQ个人消息:{ids}推送成功!")
723
+ else:
724
+ print(f"QQ群消息:{ids}推送成功!")
725
+ else:
726
+ if chat_type == 1:
727
+ print(f"QQ个人消息:{ids}推送失败!")
728
+ else:
729
+ print(f"QQ群消息:{ids}推送失败!")
730
+
731
+
732
+ def parse_headers(headers):
733
+ if not headers:
734
+ return {}
735
+
736
+ parsed = {}
737
+ lines = headers.split("\n")
738
+
739
+ for line in lines:
740
+ i = line.find(":")
741
+ if i == -1:
742
+ continue
743
+
744
+ key = line[:i].strip().lower()
745
+ val = line[i + 1 :].strip()
746
+ parsed[key] = parsed.get(key, "") + ", " + val if key in parsed else val
747
+
748
+ return parsed
749
+
750
+
751
+ def parse_body(body, content_type):
752
+ if not body:
753
+ return ""
754
+
755
+ parsed = {}
756
+ lines = body.split("\n")
757
+
758
+ for line in lines:
759
+ i = line.find(":")
760
+ if i == -1:
761
+ continue
762
+
763
+ key = line[:i].strip().lower()
764
+ val = line[i + 1 :].strip()
765
+
766
+ if not key or key in parsed:
767
+ continue
768
+
769
+ try:
770
+ json_value = json.loads(val)
771
+ parsed[key] = json_value
772
+ except:
773
+ parsed[key] = val
774
+
775
+ if content_type == "application/x-www-form-urlencoded":
776
+ data = urlencode(parsed, doseq=True)
777
+ return data
778
+
779
+ if content_type == "application/json":
780
+ data = json.dumps(parsed)
781
+ return data
782
+
783
+ return parsed
784
+
785
+
786
+ def format_notify_content(url, body, title, content):
787
+ if "$title" not in url and "$title" not in body:
788
+ return {}
789
+
790
+ formatted_url = url.replace("$title", urllib.parse.quote_plus(title)).replace(
791
+ "$content", urllib.parse.quote_plus(content)
792
+ )
793
+ formatted_body = body.replace("$title", title).replace("$content", content)
794
+
795
+ return formatted_url, formatted_body
796
+
797
+
798
+ def custom_notify(title: str, content: str) -> None:
799
+ """
800
+ 通过 自定义通知 推送消息。
801
+ """
802
+ if not push_config.get("WEBHOOK_URL") or not push_config.get("WEBHOOK_METHOD"):
803
+ print("自定义通知的 WEBHOOK_URL 或 WEBHOOK_METHOD 未设置!!\n取消推送")
804
+ return
805
+
806
+ print("自定义通知服务启动")
807
+
808
+ WEBHOOK_URL = push_config.get("WEBHOOK_URL")
809
+ WEBHOOK_METHOD = push_config.get("WEBHOOK_METHOD")
810
+ WEBHOOK_CONTENT_TYPE = push_config.get("WEBHOOK_CONTENT_TYPE")
811
+ WEBHOOK_BODY = push_config.get("WEBHOOK_BODY")
812
+ WEBHOOK_HEADERS = push_config.get("WEBHOOK_HEADERS")
813
+
814
+ formatUrl, formatBody = format_notify_content(
815
+ WEBHOOK_URL, WEBHOOK_BODY, title, content
816
+ )
817
+
818
+ if not formatUrl and not formatBody:
819
+ print("请求头或者请求体中必须包含 $title 和 $content")
820
+ return
821
+
822
+ headers = parse_headers(WEBHOOK_HEADERS)
823
+ body = parse_body(formatBody, WEBHOOK_CONTENT_TYPE)
824
+ response = requests.request(
825
+ method=WEBHOOK_METHOD, url=formatUrl, headers=headers, timeout=15, data=body
826
+ )
827
+
828
+ if response.status_code == 200:
829
+ print("自定义通知推送成功!")
830
+ else:
831
+ print(f"自定义通知推送失败!{response.status_code} {response.text}")
832
+
833
+
668
834
  def one() -> str:
669
835
  """
670
836
  获取一条一言。
@@ -721,6 +887,14 @@ if (
721
887
  notify_function.append(smtp)
722
888
  if push_config.get("PUSHME_KEY"):
723
889
  notify_function.append(pushme)
890
+ if (
891
+ push_config.get("CHRONOCAT_URL")
892
+ and push_config.get("CHRONOCAT_QQ")
893
+ and push_config.get("CHRONOCAT_TOKEN")
894
+ ):
895
+ notify_function.append(chronocat)
896
+ if push_config.get("WEBHOOK_URL") and push_config.get("WEBHOOK_METHOD"):
897
+ notify_function.append(custom_notify)
724
898
 
725
899
 
726
900
  def send(title: str, content: str) -> None:
package/shell/otask.sh CHANGED
@@ -89,7 +89,7 @@ run_normal() {
89
89
  file_param=${file_param/$relative_path\//}
90
90
  fi
91
91
 
92
- $timeoutCmd $which_program $file_param
92
+ $timeoutCmd $which_program $file_param "${script_params[@]}"
93
93
  }
94
94
 
95
95
  ## 并发执行时,设定的 RandomDelay 不会生效,即所有任务立即执行
@@ -131,7 +131,7 @@ run_concurrent() {
131
131
  for i in "${!array[@]}"; do
132
132
  export "${env_param}=${array[i]}"
133
133
  single_log_path="$dir_log/$log_dir/${single_log_time}_$((i + 1)).log"
134
- eval $timeoutCmd $which_program $file_param &>$single_log_path &
134
+ eval $timeoutCmd $which_program $file_param "${script_params[@]}" &>$single_log_path &
135
135
  done
136
136
 
137
137
  wait
@@ -174,7 +174,7 @@ run_designated() {
174
174
  cd ${relative_path}
175
175
  file_param=${file_param/$relative_path\//}
176
176
  fi
177
- $timeoutCmd $which_program $file_param
177
+ $timeoutCmd $which_program $file_param "${script_params[@]}"
178
178
  }
179
179
 
180
180
  ## 运行其他命令
@@ -225,6 +225,8 @@ main() {
225
225
  fi
226
226
  }
227
227
 
228
- handle_task_before "$@"
229
- main "$@"
230
- handle_task_after "$@"
228
+ handle_task_start "${task_shell_params[@]}"
229
+ run_task_before "${task_shell_params[@]}"
230
+ main "${task_shell_params[@]}"
231
+ run_task_after "${task_shell_params[@]}"
232
+ handle_task_end "${task_shell_params[@]}"
package/shell/share.sh CHANGED
@@ -105,9 +105,6 @@ set_proxy() {
105
105
  unset_proxy() {
106
106
  unset http_proxy
107
107
  unset https_proxy
108
- unset ftp_proxy
109
- unset all_proxy
110
- unset no_proxy
111
108
  }
112
109
 
113
110
  make_dir() {
@@ -316,10 +313,8 @@ random_range() {
316
313
 
317
314
  reload_pm2() {
318
315
  cd $dir_root
319
- # 代理会影响 grpc 服务
320
- unset_proxy
321
316
  pm2 flush &>/dev/null
322
- pm2 startOrGracefulReload $file_ecosystem_js --update-env
317
+ env ALL_PROXY= HTTP_PROXY= HTTPS_PROXY= all_proxy= http_proxy= https_proxy= pm2 startOrGracefulReload $file_ecosystem_js --update-env
323
318
  }
324
319
 
325
320
  diff_time() {
@@ -412,8 +407,18 @@ init_nginx() {
412
407
  local aliasStr=""
413
408
  local rootStr=""
414
409
  if [[ $ql_base_url != "/" ]]; then
410
+ if [[ $ql_base_url != /* ]]; then
411
+ ql_base_url="/$ql_base_url"
412
+ fi
413
+ if [[ $ql_base_url != */ ]]; then
414
+ ql_base_url="$ql_base_url/"
415
+ fi
415
416
  location_url="^~${ql_base_url%*/}"
416
417
  aliasStr="alias ${dir_static}/dist;"
418
+ if ! grep -q "<base href=\"$ql_base_url\">" "${dir_static}/dist/index.html"; then
419
+ awk -v text="<base href=\"$ql_base_url\">" '/<link/ && !inserted {print text; inserted=1} 1' "${dir_static}/dist/index.html" >temp.html
420
+ mv temp.html "${dir_static}/dist/index.html"
421
+ fi
417
422
  else
418
423
  rootStr="root ${dir_static}/dist;"
419
424
  fi
@@ -433,10 +438,13 @@ init_nginx() {
433
438
  sed -i "s,IPV4_CONFIG,${ipv4Str},g" /etc/nginx/conf.d/front.conf
434
439
  }
435
440
 
436
- handle_task_before() {
441
+ handle_task_start() {
437
442
  [[ $ID ]] && update_cron "\"$ID\"" "0" "$$" "$log_path" "$begin_timestamp"
438
-
439
443
  echo -e "## 开始执行... $begin_time\n"
444
+ }
445
+
446
+ run_task_before() {
447
+ [[ $is_macos -eq 0 ]] && check_server
440
448
 
441
449
  . $file_task_before "$@"
442
450
 
@@ -447,7 +455,7 @@ handle_task_before() {
447
455
  fi
448
456
  }
449
457
 
450
- handle_task_after() {
458
+ run_task_after() {
451
459
  . $file_task_after "$@"
452
460
 
453
461
  if [[ $task_after ]]; then
@@ -455,7 +463,9 @@ handle_task_after() {
455
463
  eval "$task_after"
456
464
  echo -e "\n执行后置命令结束"
457
465
  fi
466
+ }
458
467
 
468
+ handle_task_end() {
459
469
  local etime=$(date "+$time_format")
460
470
  local end_time=$(format_time "$time_format" "$etime")
461
471
  local end_timestamp=$(format_timestamp "$time_format" "$etime")
@@ -463,8 +473,7 @@ handle_task_after() {
463
473
 
464
474
  [[ "$diff_time" == 0 ]] && diff_time=1
465
475
 
466
- echo -e "\n\n## 执行结束... $end_time 耗时 $diff_time 秒     "
467
-
476
+ echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒     "
468
477
  [[ $ID ]] && update_cron "\"$ID\"" "1" "" "$log_path" "$begin_timestamp" "$diff_time"
469
478
  }
470
479
 
package/shell/task.sh CHANGED
@@ -5,9 +5,9 @@ dir_shell=$QL_DIR/shell
5
5
  . $dir_shell/share.sh
6
6
  . $dir_shell/api.sh
7
7
 
8
- trap "single_hanle" 2 3 20 15 14
8
+ trap "single_hanle" 2 3 20 15 14 19 1
9
9
  single_hanle() {
10
- eval handle_task_after "$@" "$cmd"
10
+ eval handle_task_end "$@" "$cmd"
11
11
  exit 1
12
12
  }
13
13
 
@@ -95,6 +95,21 @@ format_params() {
95
95
  fi
96
96
  fi
97
97
  # params=$(echo "$@" | sed -E 's/([^ ])&([^ ])/\1\\\&\2/g')
98
+
99
+ # 分割 task 内置参数和脚本参数
100
+ task_shell_params=()
101
+ script_params=()
102
+ found_double_dash=false
103
+
104
+ for arg in "$@"; do
105
+ if $found_double_dash; then
106
+ script_params+=("$arg")
107
+ elif [ "$arg" == "--" ]; then
108
+ found_double_dash=true
109
+ else
110
+ task_shell_params+=("$arg")
111
+ fi
112
+ done
98
113
  }
99
114
 
100
115
  init_begin_time() {
@@ -119,11 +134,12 @@ if [[ $max_time ]]; then
119
134
  fi
120
135
 
121
136
  format_params "$@"
122
- define_program "$@"
123
- handle_log_path "$@"
137
+ define_program "${task_shell_params[@]}"
138
+ handle_log_path "${task_shell_params[@]}"
124
139
  init_begin_time
125
140
 
126
141
  eval . $dir_shell/otask.sh "$cmd"
127
- [[ -f "$dir_log/$log_path" ]] && [[ ! $show_log ]] && [[ "$real_time" != "true" ]] && cat "$dir_log/$log_path"
142
+ # mac cat 无法正常退出
143
+ # [[ -f "$dir_log/$log_path" ]] && [[ ! $show_log ]] && [[ "$real_time" != "true" ]] && cat "$dir_log/$log_path"
128
144
 
129
145
  exit 0
@@ -370,10 +370,9 @@ exports.default = (app) => {
370
370
  last_execution_time: celebrate_1.Joi.number().optional().allow(null),
371
371
  }),
372
372
  }), async (req, res, next) => {
373
- const logger = typedi_1.Container.get('logger');
374
373
  try {
375
374
  const cronService = typedi_1.Container.get(cron_1.default);
376
- const data = await cronService.status(Object.assign(Object.assign({}, req.body), { status: parseInt(req.body.status), pid: parseInt(req.body.pid) || '' }));
375
+ const data = await cronService.status(Object.assign(Object.assign({}, req.body), { status: req.body.status ? parseInt(req.body.status) : undefined, pid: req.body.pid ? parseInt(req.body.pid) : undefined }));
377
376
  return res.send({ code: 200, data });
378
377
  }
379
378
  catch (e) {
@@ -76,7 +76,7 @@ exports.default = (app) => {
76
76
  let { filename, path, type } = req.body;
77
77
  const filePath = (0, path_1.join)(config_1.default.logPath, path, filename);
78
78
  if (type === 'directory') {
79
- (0, util_1.emptyDir)(filePath);
79
+ await (0, util_1.emptyDir)(filePath);
80
80
  }
81
81
  else {
82
82
  fs.unlinkSync(filePath);
@@ -155,7 +155,7 @@ exports.default = (app) => {
155
155
  let { filename, path, type } = req.body;
156
156
  const filePath = (0, path_1.join)(config_1.default.scriptPath, path, filename);
157
157
  if (type === 'directory') {
158
- (0, util_1.emptyDir)(filePath);
158
+ await (0, util_1.emptyDir)(filePath);
159
159
  }
160
160
  else {
161
161
  fs.unlinkSync(filePath);
@@ -218,7 +218,6 @@ exports.default = (app) => {
218
218
  pid: celebrate_1.Joi.number().optional().allow(''),
219
219
  }),
220
220
  }), async (req, res, next) => {
221
- const logger = typedi_1.Container.get('logger');
222
221
  try {
223
222
  let { filename, path, pid } = req.body;
224
223
  const { name, ext } = (0, path_1.parse)(filename);
@@ -226,7 +225,9 @@ exports.default = (app) => {
226
225
  const logPath = (0, path_1.join)(config_1.default.logPath, path, `${name}.swap`);
227
226
  const scriptService = typedi_1.Container.get(script_1.default);
228
227
  const result = await scriptService.stopScript(filePath, pid);
229
- (0, util_1.emptyDir)(logPath);
228
+ setTimeout(() => {
229
+ (0, util_1.emptyDir)(logPath);
230
+ }, 3000);
230
231
  res.send(result);
231
232
  }
232
233
  catch (e) {
@@ -10,6 +10,14 @@ function getPickedEnv() {
10
10
  if (pickedEnv)
11
11
  return pickedEnv;
12
12
  const picked = (0, pick_1.default)(process.env, ['QlBaseUrl', 'DeployEnv']);
13
+ if (picked.QlBaseUrl) {
14
+ if (!picked.QlBaseUrl.startsWith('/')) {
15
+ picked.QlBaseUrl = `/${picked.QlBaseUrl}`;
16
+ }
17
+ if (!picked.QlBaseUrl.endsWith('/')) {
18
+ picked.QlBaseUrl = `${picked.QlBaseUrl}/`;
19
+ }
20
+ }
13
21
  pickedEnv = picked;
14
22
  return picked;
15
23
  }
@@ -109,6 +109,9 @@ async function getNetIp(req) {
109
109
  if (ip.includes('127.0') || ip.includes('192.168') || ip.includes('10.7')) {
110
110
  ip = '';
111
111
  }
112
+ if (!ip) {
113
+ return { address: `获取失败`, ip };
114
+ }
112
115
  try {
113
116
  const baiduApi = got_1.default
114
117
  .get(`https://www.cip.cc/${ip}`, { timeout: 10000, retry: 0 })
@@ -300,18 +303,22 @@ function readDir(dir, baseDir = '', blacklist = []) {
300
303
  return result;
301
304
  }
302
305
  exports.readDir = readDir;
303
- function emptyDir(path) {
306
+ async function emptyDir(path) {
307
+ const pathExist = await fileExist(path);
308
+ if (!pathExist) {
309
+ return;
310
+ }
304
311
  const files = fs.readdirSync(path);
305
- files.forEach((file) => {
312
+ for (const file of files) {
306
313
  const filePath = `${path}/${file}`;
307
314
  const stats = fs.statSync(filePath);
308
315
  if (stats.isDirectory()) {
309
- emptyDir(filePath);
316
+ await emptyDir(filePath);
310
317
  }
311
318
  else {
312
319
  fs.unlinkSync(filePath);
313
320
  }
314
- });
321
+ }
315
322
  fs.rmdirSync(path);
316
323
  }
317
324
  exports.emptyDir = emptyDir;
@@ -405,11 +412,10 @@ function psTree(pid) {
405
412
  exports.psTree = psTree;
406
413
  async function killTask(pid) {
407
414
  const pids = await psTree(pid);
408
- // SIGINT 2 程序终止(interrupt)信号,不会打印额外信息
409
415
  if (pids.length) {
410
416
  try {
411
- [pid, ...pids].forEach((x) => {
412
- process.kill(x, 2);
417
+ [pid, ...pids].reverse().forEach((x) => {
418
+ process.kill(x, 15);
413
419
  });
414
420
  }
415
421
  catch (error) { }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LarkNotification = exports.WebhookNotification = exports.PushMeNotification = exports.EmailNotification = exports.PushPlusNotification = exports.IGotNotification = exports.AibotkNotification = exports.WeWorkAppNotification = exports.WeWorkBotNotification = exports.DingtalkBotNotification = exports.TelegramBotNotification = exports.BarkNotification = exports.ChatNotification = exports.PushDeerNotification = exports.ServerChanNotification = exports.GoCqHttpBotNotification = exports.GotifyNotification = exports.NotificationMode = void 0;
3
+ exports.LarkNotification = exports.WebhookNotification = exports.ChronocatNotification = exports.PushMeNotification = exports.EmailNotification = exports.PushPlusNotification = exports.IGotNotification = exports.AibotkNotification = exports.WeWorkAppNotification = exports.WeWorkBotNotification = exports.DingtalkBotNotification = exports.TelegramBotNotification = exports.BarkNotification = exports.ChatNotification = exports.PushDeerNotification = exports.ServerChanNotification = exports.GoCqHttpBotNotification = exports.GotifyNotification = exports.NotificationMode = void 0;
4
4
  var NotificationMode;
5
5
  (function (NotificationMode) {
6
6
  NotificationMode["gotify"] = "gotify";
@@ -20,6 +20,7 @@ var NotificationMode;
20
20
  NotificationMode["pushMe"] = "pushMe";
21
21
  NotificationMode["feishu"] = "feishu";
22
22
  NotificationMode["webhook"] = "webhook";
23
+ NotificationMode["chronocat"] = "Chronocat";
23
24
  })(NotificationMode || (exports.NotificationMode = NotificationMode = {}));
24
25
  class NotificationBaseInfo {
25
26
  }
@@ -152,6 +153,15 @@ class PushMeNotification extends NotificationBaseInfo {
152
153
  }
153
154
  }
154
155
  exports.PushMeNotification = PushMeNotification;
156
+ class ChronocatNotification extends NotificationBaseInfo {
157
+ constructor() {
158
+ super(...arguments);
159
+ this.chronocatURL = '';
160
+ this.chronocatQQ = '';
161
+ this.chronocatToekn = '';
162
+ }
163
+ }
164
+ exports.ChronocatNotification = ChronocatNotification;
155
165
  class WebhookNotification extends NotificationBaseInfo {
156
166
  constructor() {
157
167
  super(...arguments);
@@ -31,13 +31,9 @@ exports.default = async ({ server }) => {
31
31
  });
32
32
  process.on('uncaughtException', (error) => {
33
33
  logger_1.default.error('Uncaught exception:', error);
34
- console.error('Uncaught exception:', error);
35
- process.exit(1);
36
34
  });
37
35
  process.on('unhandledRejection', (reason, promise) => {
38
36
  logger_1.default.error('Unhandled rejection:', reason, promise);
39
- console.error('Unhandled rejection:', reason, promise);
40
- process.exit(1);
41
37
  });
42
38
  };
43
39
  //# sourceMappingURL=server.js.map
@@ -58,7 +58,7 @@ exports.ISchedule = {
58
58
  },
59
59
  };
60
60
  function createBaseICron() {
61
- return { id: "", schedule: "", command: "", extraSchedules: [] };
61
+ return { id: "", schedule: "", command: "", extraSchedules: [], name: "" };
62
62
  }
63
63
  exports.ICron = {
64
64
  encode(message, writer = minimal_1.default.Writer.create()) {
@@ -74,6 +74,9 @@ exports.ICron = {
74
74
  for (const v of message.extraSchedules) {
75
75
  exports.ISchedule.encode(v, writer.uint32(34).fork()).ldelim();
76
76
  }
77
+ if (message.name !== "") {
78
+ writer.uint32(42).string(message.name);
79
+ }
77
80
  return writer;
78
81
  },
79
82
  decode(input, length) {
@@ -107,6 +110,12 @@ exports.ICron = {
107
110
  }
108
111
  message.extraSchedules.push(exports.ISchedule.decode(reader, reader.uint32()));
109
112
  continue;
113
+ case 5:
114
+ if (tag !== 42) {
115
+ break;
116
+ }
117
+ message.name = reader.string();
118
+ continue;
110
119
  }
111
120
  if ((tag & 7) === 4 || tag === 0) {
112
121
  break;
@@ -123,6 +132,7 @@ exports.ICron = {
123
132
  extraSchedules: Array.isArray(object === null || object === void 0 ? void 0 : object.extraSchedules)
124
133
  ? object.extraSchedules.map((e) => exports.ISchedule.fromJSON(e))
125
134
  : [],
135
+ name: isSet(object.name) ? String(object.name) : "",
126
136
  };
127
137
  },
128
138
  toJSON(message) {
@@ -136,18 +146,20 @@ exports.ICron = {
136
146
  else {
137
147
  obj.extraSchedules = [];
138
148
  }
149
+ message.name !== undefined && (obj.name = message.name);
139
150
  return obj;
140
151
  },
141
152
  create(base) {
142
153
  return exports.ICron.fromPartial(base !== null && base !== void 0 ? base : {});
143
154
  },
144
155
  fromPartial(object) {
145
- var _a, _b, _c, _d;
156
+ var _a, _b, _c, _d, _e;
146
157
  const message = createBaseICron();
147
158
  message.id = (_a = object.id) !== null && _a !== void 0 ? _a : "";
148
159
  message.schedule = (_b = object.schedule) !== null && _b !== void 0 ? _b : "";
149
160
  message.command = (_c = object.command) !== null && _c !== void 0 ? _c : "";
150
161
  message.extraSchedules = ((_d = object.extraSchedules) === null || _d === void 0 ? void 0 : _d.map((e) => exports.ISchedule.fromPartial(e))) || [];
162
+ message.name = (_e = object.name) !== null && _e !== void 0 ? _e : "";
151
163
  return message;
152
164
  },
153
165
  };
@@ -11,25 +11,25 @@ const logger_1 = __importDefault(require("../loaders/logger"));
11
11
  const addCron = (call, callback) => {
12
12
  var _a;
13
13
  for (const item of call.request.crons) {
14
- const { id, schedule, command, extraSchedules } = item;
14
+ const { id, schedule, command, extraSchedules, name } = item;
15
15
  if (data_1.scheduleStacks.has(id)) {
16
16
  (_a = data_1.scheduleStacks.get(id)) === null || _a === void 0 ? void 0 : _a.forEach((x) => x.cancel());
17
17
  }
18
- logger_1.default.info('[schedule][创建定时任务], 任务ID: %s, cron: %s, 执行命令: %s', id, schedule, command);
18
+ logger_1.default.info('[schedule][创建定时任务], 任务ID: %s, 名称: %s, cron: %s, 执行命令: %s', id, name, schedule, command);
19
19
  if (extraSchedules === null || extraSchedules === void 0 ? void 0 : extraSchedules.length) {
20
20
  extraSchedules.forEach(x => {
21
- logger_1.default.info('[schedule][创建定时任务], 任务ID: %s, cron: %s, 执行命令: %s', id, x.schedule, command);
21
+ logger_1.default.info('[schedule][创建定时任务], 任务ID: %s, 名称: %s, cron: %s, 执行命令: %s', id, name, x.schedule, command);
22
22
  });
23
23
  }
24
24
  data_1.scheduleStacks.set(id, [
25
25
  node_schedule_1.default.scheduleJob(id, schedule, async () => {
26
26
  logger_1.default.info(`[schedule][准备运行任务] 命令: ${command}`);
27
- (0, runCron_1.runCron)(command);
27
+ (0, runCron_1.runCron)(command, { name, schedule, extraSchedules });
28
28
  }),
29
29
  ...((extraSchedules === null || extraSchedules === void 0 ? void 0 : extraSchedules.length)
30
30
  ? extraSchedules.map((x) => node_schedule_1.default.scheduleJob(id, x.schedule, async () => {
31
31
  logger_1.default.info(`[schedule][准备运行任务] 命令: ${command}`);
32
- (0, runCron_1.runCron)(command);
32
+ (0, runCron_1.runCron)(command, { name, schedule, extraSchedules });
33
33
  }))
34
34
  : []),
35
35
  ]);