diff --git a/-H b/-H
new file mode 100644
index 0000000..9d20070
--- /dev/null
+++ b/-H
@@ -0,0 +1,6 @@
+HTTP/1.1 411 Length Required
+Content-Type: text/html; charset=us-ascii
+Date: Fri, 03 Nov 2023 16:19:55 GMT
+Connection: close
+Content-Length: 344
+
diff --git a/-s b/-s
new file mode 100644
index 0000000..c8f11ce
--- /dev/null
+++ b/-s
@@ -0,0 +1,9 @@
+HTTP/1.1 100 Continue
+
+HTTP/1.1 202 Accepted
+Content-Length: 0
+Location: 9a95fdfe-adfe-4e98-be34-70d029205fea
+Strict-Transport-Security: max-age=31536000; includeSubDomains
+Request-Context: appId=cid-v1:23f44029-850d-47f4-8c9f-200d01ff4866
+Date: Fri, 03 Nov 2023 16:20:15 GMT
+
diff --git a/README.md b/README.md
index caac5d9..bb6f8fc 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,3 @@
-# BotExt
-
-Chrome 插件
+# BotExt
+
+Chrome 插件
diff --git a/botext/__init__.py b/botext/__init__.py
index 8cb3f9e..6ee4978 100644
--- a/botext/__init__.py
+++ b/botext/__init__.py
@@ -1,49 +1,49 @@
-import win32pipe
-import win32file
-import struct
-
-
-class HostClient:
- def __init__(self):
- self.pipe_name = r"\\.\pipe\BotExtPipe"
- self.pipe = None
-
- def connect(self):
- self.pipe = win32file.CreateFile(
- self.pipe_name,
- win32file.GENERIC_READ | win32file.GENERIC_WRITE,
- 0,
- None,
- win32file.OPEN_EXISTING,
- 0,
- None,
- )
-
- def write(self, data):
- if not self.pipe:
- self.connect()
- length = len(data)
- length_bytes = struct.pack("I", length)
- win32file.WriteFile(self.pipe, length_bytes)
- win32file.WriteFile(self.pipe, data)
-
- def read(self):
- if not self.pipe:
- self.connect()
- length_bytes = win32file.ReadFile(self.pipe, 4)[1]
- length = struct.unpack("I", length_bytes)[0]
- data = win32file.ReadFile(self.pipe, length)[1]
- return data
-
- def close(self):
- if self.pipe:
- win32file.CloseHandle(self.pipe)
- self.pipe = None
-
-
-if __name__ == "__main__":
- client = HostClient()
- client.connect()
- client.write(b"Hello, World!")
- print(client.read())
- client.close()
+import win32pipe
+import win32file
+import struct
+
+
+class HostClient:
+ def __init__(self):
+ self.pipe_name = r"\\.\pipe\BotExtPipe"
+ self.pipe = None
+
+ def connect(self):
+ self.pipe = win32file.CreateFile(
+ self.pipe_name,
+ win32file.GENERIC_READ | win32file.GENERIC_WRITE,
+ 0,
+ None,
+ win32file.OPEN_EXISTING,
+ 0,
+ None,
+ )
+
+ def write(self, data):
+ if not self.pipe:
+ self.connect()
+ length = len(data)
+ length_bytes = struct.pack("I", length)
+ win32file.WriteFile(self.pipe, length_bytes)
+ win32file.WriteFile(self.pipe, data)
+
+ def read(self):
+ if not self.pipe:
+ self.connect()
+ length_bytes = win32file.ReadFile(self.pipe, 4)[1]
+ length = struct.unpack("I", length_bytes)[0]
+ data = win32file.ReadFile(self.pipe, length)[1]
+ return data
+
+ def close(self):
+ if self.pipe:
+ win32file.CloseHandle(self.pipe)
+ self.pipe = None
+
+
+if __name__ == "__main__":
+ client = HostClient()
+ client.connect()
+ client.write(b"Hello, World!")
+ print(client.read())
+ client.close()
diff --git a/botext/console/install_host.bat b/botext/console/install_host.bat
index e995453..d007436 100644
--- a/botext/console/install_host.bat
+++ b/botext/console/install_host.bat
@@ -1,7 +1,7 @@
-:: Copyright 2014 The Chromium Authors. All rights reserved.
-:: Use of this source code is governed by a BSD-style license that can be
-:: found in the LICENSE file.
-
-:: Change HKCU to HKLM if you want to install globally.
-:: %~dp0 is the directory containing this bat script and ends with a backslash.
-REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.woni.botext" /ve /t REG_SZ /d "%~dp0com.google.chrome.botext.json" /f
+:: Copyright 2014 The Chromium Authors. All rights reserved.
+:: Use of this source code is governed by a BSD-style license that can be
+:: found in the LICENSE file.
+
+:: Change HKCU to HKLM if you want to install globally.
+:: %~dp0 is the directory containing this bat script and ends with a backslash.
+REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.woni.botext" /ve /t REG_SZ /d "%~dp0com.google.chrome.botext.json" /f
diff --git a/botext/install.py b/botext/install.py
index c8b2e1b..c4a34d4 100644
--- a/botext/install.py
+++ b/botext/install.py
@@ -1,21 +1,21 @@
-import os
-
-
-# 在下载文件夹创建test目录
-# 获取windows 下载文件夹路径
-def get_download_folder():
- home_dir = os.path.expanduser("~")
- download_folder = os.path.join(home_dir, "Downloads")
- return download_folder
-
-def main():
- # download_path = get_download_folder()
- # test = os.path.join(download_path, "test")
- # if not os.path.exists(test):
- # os.mkdir(test)
- print("install_host.bat")
- # os.system("install_host.bat")
-
-
-if __name__ == '__main__':
- main()
+import os
+
+
+# 在下载文件夹创建test目录
+# 获取windows 下载文件夹路径
+def get_download_folder():
+ home_dir = os.path.expanduser("~")
+ download_folder = os.path.join(home_dir, "Downloads")
+ return download_folder
+
+def main():
+ # download_path = get_download_folder()
+ # test = os.path.join(download_path, "test")
+ # if not os.path.exists(test):
+ # os.mkdir(test)
+ print("install_host.bat")
+ # os.system("install_host.bat")
+
+
+if __name__ == '__main__':
+ main()
diff --git a/bridge/botext.bat b/bridge/botext.bat
index 13a64f1..c2ccdc6 100644
--- a/bridge/botext.bat
+++ b/bridge/botext.bat
@@ -1,4 +1,4 @@
-@echo off
-
-
-python "%~dp0/native-messaging-example-host" %*
+@echo off
+
+
+python "%~dp0/native-messaging-example-host" %*
diff --git a/bridge/client.py b/bridge/client.py
index 634982e..d536cb2 100644
--- a/bridge/client.py
+++ b/bridge/client.py
@@ -1,19 +1,19 @@
-import win32pipe
-import win32file
-
-# 连接到命名管道
-pipe_name = r'\\.\pipe\botext'
-pipe = win32file.CreateFile(
- pipe_name,
- win32file.GENERIC_READ | win32file.GENERIC_WRITE,
- 0,
- None,
- win32file.OPEN_EXISTING,
- 0,
- None
-)
-
-win32file.WriteFile(pipe, b'close1')
-
-# 关闭管道
-win32file.CloseHandle(pipe)
+import win32pipe
+import win32file
+
+# 连接到命名管道
+pipe_name = r'\\.\pipe\botext'
+pipe = win32file.CreateFile(
+ pipe_name,
+ win32file.GENERIC_READ | win32file.GENERIC_WRITE,
+ 0,
+ None,
+ win32file.OPEN_EXISTING,
+ 0,
+ None
+)
+
+win32file.WriteFile(pipe, b'close1')
+
+# 关闭管道
+win32file.CloseHandle(pipe)
diff --git a/bridge/com.woni.chrome.botext.json b/bridge/com.woni.chrome.botext.json
index ffd72df..f38c001 100644
--- a/bridge/com.woni.chrome.botext.json
+++ b/bridge/com.woni.chrome.botext.json
@@ -1,9 +1,9 @@
-{
- "name": "com.woni.chrome.botext",
- "description": "botext",
- "path": "D:\\CS\\BotBridge\\bin\\Debug\\net8.0\\BotBridge.exe",
- "type": "stdio",
- "allowed_origins": [
- "chrome-extension://hhfenmonendjidnaibblhgkapmbncmnp/"
- ]
-}
+{
+ "name": "com.woni.chrome.botext",
+ "description": "botext",
+ "path": "D:\\CS\\BotBridge\\bin\\Debug\\net8.0\\BotBridge.exe",
+ "type": "stdio",
+ "allowed_origins": [
+ "chrome-extension://hhfenmonendjidnaibblhgkapmbncmnp/"
+ ]
+}
diff --git a/bridge/native-messaging-example-host b/bridge/native-messaging-example-host
index f14e005..7ae9cce 100644
--- a/bridge/native-messaging-example-host
+++ b/bridge/native-messaging-example-host
@@ -1,82 +1,82 @@
-import sys
-import struct
-import ctypes
-import threading
-import win32pipe
-import win32file
-
-
-pipe_name = r"\\.\pipe\botext"
-pipe_access = win32pipe.PIPE_ACCESS_DUPLEX
-pipe_type =win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_WAIT | win32pipe.PIPE_READMODE_MESSAGE
-pipe_mode = win32pipe.PIPE_UNLIMITED_INSTANCES
-max_instances = 65536
-out_buffer_size = 65536
-default_time_out = 0
-security_attributes = None
-
-
-pipe = win32pipe.CreateNamedPipe(
- pipe_name,
- pipe_access,
- pipe_type,
- pipe_mode,
- max_instances,
- out_buffer_size,
- default_time_out,
- security_attributes,
-)
-
-
-def write_data(data):
- msglen = len(data)
- msglen_bytes = struct.pack("=I", msglen)
- sys.stdout.buffer.write(msglen_bytes)
- sys.stdout.buffer.write(data.encode())
- sys.stdout.buffer.flush()
-
-
-def read_thread_func():
- while True:
- raw_msglen = sys.stdin.buffer.read(4)
- if not raw_msglen:
- sys.exit(0)
- msglen = struct.unpack("=I", raw_msglen)[0]
-
- # Read the message data
- data = sys.stdin.buffer.read(msglen)
- ctypes.windll.user32.MessageBoxW(0, data.decode(), "BotExt", 0)
- write_data('{"msg": "bridge"}')
-
-
-def namepipe_server(pipe):
- try:
- while True:
- win32pipe.ConnectNamedPipe(pipe, None)
- _, data = win32file.ReadFile(pipe, 4096)
- if data == b"close":
- sys.exit(0)
- print(data)
- write_data('{"msg": "client"}')
- # ctypes.windll.user32.MessageBoxW(0, "hi", "BotExt", 0)
- win32pipe.DisconnectNamedPipe(pipe)
- except Exception as e:
- win32pipe.DisconnectNamedPipe(pipe)
- finally:
- win32file.CloseHandle(pipe)
-
-
-def namepipe_server_forver(pipe):
- while True:
- namepipe_server(pipe)
-
-
-if __name__ == "__main__":
- thread = threading.Thread(target=read_thread_func)
- thread2 = threading.Thread(target=namepipe_server_forver, args=(pipe,))
- thread.daemon = True
- thread2.daemon = True
- thread.start()
- thread2.start()
- thread.join()
- thread2.join()
+import sys
+import struct
+import ctypes
+import threading
+import win32pipe
+import win32file
+
+
+pipe_name = r"\\.\pipe\botext"
+pipe_access = win32pipe.PIPE_ACCESS_DUPLEX
+pipe_type =win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_WAIT | win32pipe.PIPE_READMODE_MESSAGE
+pipe_mode = win32pipe.PIPE_UNLIMITED_INSTANCES
+max_instances = 65536
+out_buffer_size = 65536
+default_time_out = 0
+security_attributes = None
+
+
+pipe = win32pipe.CreateNamedPipe(
+ pipe_name,
+ pipe_access,
+ pipe_type,
+ pipe_mode,
+ max_instances,
+ out_buffer_size,
+ default_time_out,
+ security_attributes,
+)
+
+
+def write_data(data):
+ msglen = len(data)
+ msglen_bytes = struct.pack("=I", msglen)
+ sys.stdout.buffer.write(msglen_bytes)
+ sys.stdout.buffer.write(data.encode())
+ sys.stdout.buffer.flush()
+
+
+def read_thread_func():
+ while True:
+ raw_msglen = sys.stdin.buffer.read(4)
+ if not raw_msglen:
+ sys.exit(0)
+ msglen = struct.unpack("=I", raw_msglen)[0]
+
+ # Read the message data
+ data = sys.stdin.buffer.read(msglen)
+ ctypes.windll.user32.MessageBoxW(0, data.decode(), "BotExt", 0)
+ write_data('{"msg": "bridge"}')
+
+
+def namepipe_server(pipe):
+ try:
+ while True:
+ win32pipe.ConnectNamedPipe(pipe, None)
+ _, data = win32file.ReadFile(pipe, 4096)
+ if data == b"close":
+ sys.exit(0)
+ print(data)
+ write_data('{"msg": "client"}')
+ # ctypes.windll.user32.MessageBoxW(0, "hi", "BotExt", 0)
+ win32pipe.DisconnectNamedPipe(pipe)
+ except Exception as e:
+ win32pipe.DisconnectNamedPipe(pipe)
+ finally:
+ win32file.CloseHandle(pipe)
+
+
+def namepipe_server_forver(pipe):
+ while True:
+ namepipe_server(pipe)
+
+
+if __name__ == "__main__":
+ thread = threading.Thread(target=read_thread_func)
+ thread2 = threading.Thread(target=namepipe_server_forver, args=(pipe,))
+ thread.daemon = True
+ thread2.daemon = True
+ thread.start()
+ thread2.start()
+ thread.join()
+ thread2.join()
diff --git a/bridge/native-messaging-example-host copy b/bridge/native-messaging-example-host copy
index 5543a4e..d05413b 100644
--- a/bridge/native-messaging-example-host copy
+++ b/bridge/native-messaging-example-host copy
@@ -1,112 +1,112 @@
-import struct
-import sys
-import threading
-from queue import Queue
-
-
-import tkinter as Tkinter
-from tkinter import messagebox as tkMessageBox
-
-if sys.platform == "win32":
- import os, msvcrt
-
- msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
- msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
-
-
-def send_message(message):
- sys.stdout.write(str(len(message)))
- sys.stdout.write(message)
- sys.stdout.flush()
-
-
-def read_thread_func(queue):
- message_number = 0
- while 1:
- text_length_bytes = sys.stdin.read(4)
- if len(text_length_bytes) == 0:
- if queue:
- queue.put(None)
- sys.exit(0)
-
- text_length = struct.unpack("i", text_length_bytes)[0]
- text = sys.stdin.read(text_length).decode("utf-8")
-
- if queue:
- queue.put(text)
- else:
- send_message('{"echo": %s}' % text)
-
-
-if Tkinter:
-
- class NativeMessagingWindow(Tkinter.Frame):
- def __init__(self, queue):
- self.queue = queue
-
- Tkinter.Frame.__init__(self)
- self.pack()
-
- self.text = Tkinter.Text(self)
- self.text.grid(row=0, column=0, padx=10, pady=10, columnspan=2)
- self.text.config(state=Tkinter.DISABLED, height=10, width=40)
-
- self.messageContent = Tkinter.StringVar()
- self.sendEntry = Tkinter.Entry(self, textvariable=self.messageContent)
- self.sendEntry.grid(row=1, column=0, padx=10, pady=10)
-
- self.sendButton = Tkinter.Button(self, text="Send", command=self.onSend)
- self.sendButton.grid(row=1, column=1, padx=10, pady=10)
-
- self.after(100, self.processMessages)
-
- def processMessages(self):
- while not self.queue.empty():
- message = self.queue.get_nowait()
- if message == None:
- self.quit()
- return
- self.log("Received %s" % message)
-
- self.after(100, self.processMessages)
-
- def onSend(self):
- text = '{"text": "' + self.messageContent.get() + '"}'
- self.log("Sending %s" % text)
- try:
- send_message(text)
- except IOError:
- tkMessageBox.showinfo(
- "Native Messaging Example", "Failed to send message."
- )
- sys.exit(1)
-
- def log(self, message):
- self.text.config(state=Tkinter.NORMAL)
- self.text.insert(Tkinter.END, message + "\n")
- self.text.config(state=Tkinter.DISABLED)
-
-
-def Main():
- if not Tkinter:
- send_message(
- "\"Tkinter python module wasn't found. Running in headless "
- + 'mode. Please consider installing Tkinter."'
- )
- read_thread_func(None)
- sys.exit(0)
-
- queue = Queue()
-
- main_window = NativeMessagingWindow(queue)
- main_window.master.title("Native Messaging Example")
-
- thread = threading.Thread(target=read_thread_func, args=(queue,))
- thread.daemon = True
- thread.start()
- main_window.mainloop()
- sys.exit(0)
-
-
-if __name__ == "__main__":
- Main()
+import struct
+import sys
+import threading
+from queue import Queue
+
+
+import tkinter as Tkinter
+from tkinter import messagebox as tkMessageBox
+
+if sys.platform == "win32":
+ import os, msvcrt
+
+ msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
+ msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
+
+
+def send_message(message):
+ sys.stdout.write(str(len(message)))
+ sys.stdout.write(message)
+ sys.stdout.flush()
+
+
+def read_thread_func(queue):
+ message_number = 0
+ while 1:
+ text_length_bytes = sys.stdin.read(4)
+ if len(text_length_bytes) == 0:
+ if queue:
+ queue.put(None)
+ sys.exit(0)
+
+ text_length = struct.unpack("i", text_length_bytes)[0]
+ text = sys.stdin.read(text_length).decode("utf-8")
+
+ if queue:
+ queue.put(text)
+ else:
+ send_message('{"echo": %s}' % text)
+
+
+if Tkinter:
+
+ class NativeMessagingWindow(Tkinter.Frame):
+ def __init__(self, queue):
+ self.queue = queue
+
+ Tkinter.Frame.__init__(self)
+ self.pack()
+
+ self.text = Tkinter.Text(self)
+ self.text.grid(row=0, column=0, padx=10, pady=10, columnspan=2)
+ self.text.config(state=Tkinter.DISABLED, height=10, width=40)
+
+ self.messageContent = Tkinter.StringVar()
+ self.sendEntry = Tkinter.Entry(self, textvariable=self.messageContent)
+ self.sendEntry.grid(row=1, column=0, padx=10, pady=10)
+
+ self.sendButton = Tkinter.Button(self, text="Send", command=self.onSend)
+ self.sendButton.grid(row=1, column=1, padx=10, pady=10)
+
+ self.after(100, self.processMessages)
+
+ def processMessages(self):
+ while not self.queue.empty():
+ message = self.queue.get_nowait()
+ if message == None:
+ self.quit()
+ return
+ self.log("Received %s" % message)
+
+ self.after(100, self.processMessages)
+
+ def onSend(self):
+ text = '{"text": "' + self.messageContent.get() + '"}'
+ self.log("Sending %s" % text)
+ try:
+ send_message(text)
+ except IOError:
+ tkMessageBox.showinfo(
+ "Native Messaging Example", "Failed to send message."
+ )
+ sys.exit(1)
+
+ def log(self, message):
+ self.text.config(state=Tkinter.NORMAL)
+ self.text.insert(Tkinter.END, message + "\n")
+ self.text.config(state=Tkinter.DISABLED)
+
+
+def Main():
+ if not Tkinter:
+ send_message(
+ "\"Tkinter python module wasn't found. Running in headless "
+ + 'mode. Please consider installing Tkinter."'
+ )
+ read_thread_func(None)
+ sys.exit(0)
+
+ queue = Queue()
+
+ main_window = NativeMessagingWindow(queue)
+ main_window.master.title("Native Messaging Example")
+
+ thread = threading.Thread(target=read_thread_func, args=(queue,))
+ thread.daemon = True
+ thread.start()
+ main_window.mainloop()
+ sys.exit(0)
+
+
+if __name__ == "__main__":
+ Main()
diff --git a/bridge/server.py b/bridge/server.py
index f720306..5aded37 100644
--- a/bridge/server.py
+++ b/bridge/server.py
@@ -1,55 +1,55 @@
-# python windows namepipe serve
-
-import win32pipe, win32file
-import json
-import threading
-import sys
-import ctypes
-
-# 连接到命名管道
-pipe_name = r"\\.\pipe\botext"
-pipe_access = win32pipe.PIPE_ACCESS_DUPLEX
-pipe_type = win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_WAIT
-pipe_mode = 1
-max_instances = 65536
-out_buffer_size = 65536
-default_time_out = 0
-security_attributes = None
-
-pipe = win32pipe.CreateNamedPipe(
- pipe_name,
- win32pipe.PIPE_ACCESS_DUPLEX,
- win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_WAIT | win32pipe.PIPE_READMODE_MESSAGE,
- win32pipe.PIPE_UNLIMITED_INSTANCES,
- 65535,
- 65535,
- 0,
- None,
-)
-
-
-def namepipe_server(pipe):
- try:
- while True:
- win32pipe.ConnectNamedPipe(pipe, None)
- _, data = win32file.ReadFile(pipe, 4096)
- if data == b'close':
- sys.exit(0)
- print(data)
- ctypes.windll.user32.MessageBoxW(0, "hi", "BotExt", 0)
- win32pipe.DisconnectNamedPipe(pipe)
- except Exception as e:
- win32pipe.DisconnectNamedPipe(pipe)
- finally:
- win32file.CloseHandle(pipe)
-
-def namepipe_server_forver(pipe):
- while True:
- namepipe_server(pipe)
-
-
-if __name__ == "__main__":
- task = threading.Thread(target=namepipe_server, args=(pipe,))
- task.daemon = True
- task.start()
- task.join()
+# python windows namepipe serve
+
+import win32pipe, win32file
+import json
+import threading
+import sys
+import ctypes
+
+# 连接到命名管道
+pipe_name = r"\\.\pipe\botext"
+pipe_access = win32pipe.PIPE_ACCESS_DUPLEX
+pipe_type = win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_WAIT
+pipe_mode = 1
+max_instances = 65536
+out_buffer_size = 65536
+default_time_out = 0
+security_attributes = None
+
+pipe = win32pipe.CreateNamedPipe(
+ pipe_name,
+ win32pipe.PIPE_ACCESS_DUPLEX,
+ win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_WAIT | win32pipe.PIPE_READMODE_MESSAGE,
+ win32pipe.PIPE_UNLIMITED_INSTANCES,
+ 65535,
+ 65535,
+ 0,
+ None,
+)
+
+
+def namepipe_server(pipe):
+ try:
+ while True:
+ win32pipe.ConnectNamedPipe(pipe, None)
+ _, data = win32file.ReadFile(pipe, 4096)
+ if data == b'close':
+ sys.exit(0)
+ print(data)
+ ctypes.windll.user32.MessageBoxW(0, "hi", "BotExt", 0)
+ win32pipe.DisconnectNamedPipe(pipe)
+ except Exception as e:
+ win32pipe.DisconnectNamedPipe(pipe)
+ finally:
+ win32file.CloseHandle(pipe)
+
+def namepipe_server_forver(pipe):
+ while True:
+ namepipe_server(pipe)
+
+
+if __name__ == "__main__":
+ task = threading.Thread(target=namepipe_server, args=(pipe,))
+ task.daemon = True
+ task.start()
+ task.join()
diff --git a/bridge/uninstall_host.bat b/bridge/uninstall_host.bat
index ca15585..2be6baf 100644
--- a/bridge/uninstall_host.bat
+++ b/bridge/uninstall_host.bat
@@ -1,7 +1,7 @@
-:: Copyright 2014 The Chromium Authors. All rights reserved.
-:: Use of this source code is governed by a BSD-style license that can be
-:: found in the LICENSE file.
-
-:: Deletes the entry created by install_host.bat
-REG DELETE "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.google.chrome.botext" /f
-REG DELETE "HKLM\Software\Google\Chrome\NativeMessagingHosts\com.google.chrome.botext" /f
+:: Copyright 2014 The Chromium Authors. All rights reserved.
+:: Use of this source code is governed by a BSD-style license that can be
+:: found in the LICENSE file.
+
+:: Deletes the entry created by install_host.bat
+REG DELETE "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.google.chrome.botext" /f
+REG DELETE "HKLM\Software\Google\Chrome\NativeMessagingHosts\com.google.chrome.botext" /f
diff --git a/build-pyd.py b/build-pyd.py
index 9759cf0..d1e5193 100644
--- a/build-pyd.py
+++ b/build-pyd.py
@@ -1,4 +1,4 @@
-from setuptools import setup
-from Cython.Build import cythonize
-
-setup(name='botext', ext_modules=cythonize('botext/__init__.py'))
+from setuptools import setup
+from Cython.Build import cythonize
+
+setup(name='botext', ext_modules=cythonize('botext/__init__.py'))
diff --git a/build.bat b/build.bat
index 0f27524..cb47ba0 100644
--- a/build.bat
+++ b/build.bat
@@ -1 +1 @@
-poetry build && pip install dist\botext-0.1.0-py3-none-any.whl --force-reinstall
+poetry build && pip install dist\botext-0.1.0-py3-none-any.whl --force-reinstall
diff --git a/crx.zip b/crx.zip
new file mode 100644
index 0000000..b74b7cf
Binary files /dev/null and b/crx.zip differ
diff --git a/crx/content-script.js b/crx/content-script.js
index 434a7ff..2c24d43 100644
--- a/crx/content-script.js
+++ b/crx/content-script.js
@@ -1,27 +1,27 @@
-
-// declare message listener from inject script
-window.addEventListener('message', (event) => {
- if (event.source === window && event.data.from === 'inject-script') {
- console.log('[Demo] receive', event.data);
-
- }
-});
-
-
-
-chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
-
-
-
- console.log('[Demo] ==============================================');
-
- const func = request.func;
- if (func === 'addRecord') {
- window.postMessage({ msg: 'ping from content script', from: 'content-script', func: 'addRecord' });
- }
- if (func === 'deleteRecord') {
- window.postMessage({ msg: 'ping from content script', from: 'content-script', func: 'deleteRecord' });
- }
- console.log('[Demo] receive', func);
- sendResponse({ response: '[Demo] pone-pone from content script' });
-});
+
+// declare message listener from inject script
+window.addEventListener('message', (event) => {
+ if (event.source === window && event.data.from === 'inject-script') {
+ console.log('[Demo] receive', event.data);
+
+ }
+});
+
+
+
+chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
+
+
+
+ console.log('[Demo] ==============================================');
+
+ const func = request.func;
+ if (func === 'addRecord') {
+ window.postMessage({ msg: 'ping from content script', from: 'content-script', func: 'addRecord' });
+ }
+ if (func === 'deleteRecord') {
+ window.postMessage({ msg: 'ping from content script', from: 'content-script', func: 'deleteRecord' });
+ }
+ console.log('[Demo] receive', func);
+ sendResponse({ response: '[Demo] pone-pone from content script' });
+});
diff --git a/crx/index.html b/crx/index.html
index 1715aa3..f9f06b1 100644
--- a/crx/index.html
+++ b/crx/index.html
@@ -1,21 +1,21 @@
-
-
-
-
-
- WpsDbSheet
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+ WpsDbSheet
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/crx/index.js b/crx/index.js
index 7026a25..1421457 100644
--- a/crx/index.js
+++ b/crx/index.js
@@ -1,86 +1,86 @@
-const DYNAMIC_SCRIPT_ID = 'add-record-script';
-
-async function isDynamicContentScriptRegistered() {
- const scripts = await chrome.scripting.getRegisteredContentScripts();
- return scripts.some((s) => s.id === DYNAMIC_SCRIPT_ID);
-}
-
-async function getActiveTab() {
- const [tab] = await chrome.tabs.query({ active: true, lastFocusedWindow: true });
- return tab;
-}
-
-
-document.querySelector('#addRecord').addEventListener('click', async () => {
-
- console.log('[Demo] ==============================================');
- console.log('[Demo] Test send message from popup script to content script');
- const tab = await getActiveTab();
- const ret = await chrome.tabs.sendMessage(tab.id, { msg: 'ping from popup script', func: 'addRecord' });
- console.log('[Demo] receive', ret);
-
-});
-
-
-document.querySelector('#deleteRecord').addEventListener('click', async () => {
-
- console.log('[Demo] ==============================================');
- console.log('[Demo] Test send message from popup script to content script');
- const tab = await getActiveTab();
- const ret = await chrome.tabs.sendMessage(tab.id, { msg: 'ping from popup script', func: 'deleteRecord' });
- console.log('[Demo] receive', ret);
-
-});
-
-
-var port = null;
-
-function appendMessage(text) {
- document.getElementById('response').innerHTML += "" + text + "
";
-}
-
-function updateUiState() {
- if (port) {
- document.getElementById('connect-button').style.display = 'none';
- document.getElementById('input-text').style.display = 'block';
- document.getElementById('send-message-button').style.display = 'block';
- } else {
- document.getElementById('connect-button').style.display = 'block';
- document.getElementById('input-text').style.display = 'none';
- document.getElementById('send-message-button').style.display = 'none';
- }
-}
-
-function sendNativeMessage() {
- message = { "text": document.getElementById('input-text').value };
- port.postMessage(message);
- appendMessage("Sent message: " + JSON.stringify(message) + "");
-}
-
-function onNativeMessage(message) {
- appendMessage("Received message: " + JSON.stringify(message) + "");
-}
-
-function onDisconnected() {
- appendMessage("Failed to connect: " + chrome.runtime.lastError.message);
- port = null;
- updateUiState();
-}
-
-function connect() {
- var hostName = "com.google.chrome.botext";
- appendMessage("Connecting to native messaging host " + hostName + "")
- port = chrome.runtime.connectNative(hostName);
- port.onMessage.addListener(onNativeMessage);
- port.onDisconnect.addListener(onDisconnected);
- updateUiState();
-}
-
-document.addEventListener('DOMContentLoaded', function () {
- document.getElementById('connect-button').addEventListener(
- 'click', connect);
- document.getElementById('send-message-button').addEventListener(
- 'click', sendNativeMessage);
- updateUiState();
-});
-
+const DYNAMIC_SCRIPT_ID = 'add-record-script';
+
+async function isDynamicContentScriptRegistered() {
+ const scripts = await chrome.scripting.getRegisteredContentScripts();
+ return scripts.some((s) => s.id === DYNAMIC_SCRIPT_ID);
+}
+
+async function getActiveTab() {
+ const [tab] = await chrome.tabs.query({ active: true, lastFocusedWindow: true });
+ return tab;
+}
+
+
+document.querySelector('#addRecord').addEventListener('click', async () => {
+
+ console.log('[Demo] ==============================================');
+ console.log('[Demo] Test send message from popup script to content script');
+ const tab = await getActiveTab();
+ const ret = await chrome.tabs.sendMessage(tab.id, { msg: 'ping from popup script', func: 'addRecord' });
+ console.log('[Demo] receive', ret);
+
+});
+
+
+document.querySelector('#deleteRecord').addEventListener('click', async () => {
+
+ console.log('[Demo] ==============================================');
+ console.log('[Demo] Test send message from popup script to content script');
+ const tab = await getActiveTab();
+ const ret = await chrome.tabs.sendMessage(tab.id, { msg: 'ping from popup script', func: 'deleteRecord' });
+ console.log('[Demo] receive', ret);
+
+});
+
+
+var port = null;
+
+function appendMessage(text) {
+ document.getElementById('response').innerHTML += "" + text + "
";
+}
+
+function updateUiState() {
+ if (port) {
+ document.getElementById('connect-button').style.display = 'none';
+ document.getElementById('input-text').style.display = 'block';
+ document.getElementById('send-message-button').style.display = 'block';
+ } else {
+ document.getElementById('connect-button').style.display = 'block';
+ document.getElementById('input-text').style.display = 'none';
+ document.getElementById('send-message-button').style.display = 'none';
+ }
+}
+
+function sendNativeMessage() {
+ message = { "text": document.getElementById('input-text').value };
+ port.postMessage(message);
+ appendMessage("Sent message: " + JSON.stringify(message) + "");
+}
+
+function onNativeMessage(message) {
+ appendMessage("Received message: " + JSON.stringify(message) + "");
+}
+
+function onDisconnected() {
+ appendMessage("Failed to connect: " + chrome.runtime.lastError.message);
+ port = null;
+ updateUiState();
+}
+
+function connect() {
+ var hostName = "com.google.chrome.botext";
+ appendMessage("Connecting to native messaging host " + hostName + "")
+ port = chrome.runtime.connectNative(hostName);
+ port.onMessage.addListener(onNativeMessage);
+ port.onDisconnect.addListener(onDisconnected);
+ updateUiState();
+}
+
+document.addEventListener('DOMContentLoaded', function () {
+ document.getElementById('connect-button').addEventListener(
+ 'click', connect);
+ document.getElementById('send-message-button').addEventListener(
+ 'click', sendNativeMessage);
+ updateUiState();
+});
+
diff --git a/crx/manifest.json b/crx/manifest.json
index 0c3a06d..be12106 100644
--- a/crx/manifest.json
+++ b/crx/manifest.json
@@ -1,52 +1,52 @@
-{
- "name": "BotExt",
- "version": "0.1.0",
- "manifest_version": 3,
- "background": {
- "service_worker": "sw.js"
- },
- "content_scripts": [
- {
- "matches": [
- "https://www.kdocs.cn/*"
- ],
- "js": [
- "content-script.js"
- ],
- "run_at": "document_end"
- },
- {
- "matches": [
- ""
- ],
- "js": [
- "wps.js"
- ],
- "run_at": "document_end",
- "world": "MAIN"
- }
- ],
- "permissions": [
- "scripting",
- "webNavigation",
- "storage",
- "activeTab",
- "nativeMessaging"
- ],
- "host_permissions": [
- "https://www.kdocs.cn/*"
- ],
- "action": {
- "default_popup": "index.html"
- },
- "web_accessible_resources": [
- {
- "resources": [
- "wps.js"
- ],
- "matches": [
- ""
- ]
- }
- ]
-}
+{
+ "name": "BotExt",
+ "version": "0.1.9",
+ "manifest_version": 3,
+ "background": {
+ "service_worker": "sw.js"
+ },
+ "content_scripts": [
+ {
+ "matches": [
+ "https://www.kdocs.cn/*"
+ ],
+ "js": [
+ "content-script.js"
+ ],
+ "run_at": "document_end"
+ },
+ {
+ "matches": [
+ ""
+ ],
+ "js": [
+ "wps.js"
+ ],
+ "run_at": "document_end",
+ "world": "MAIN"
+ }
+ ],
+ "permissions": [
+ "scripting",
+ "webNavigation",
+ "storage",
+ "activeTab",
+ "nativeMessaging"
+ ],
+ "host_permissions": [
+ "https://www.kdocs.cn/*"
+ ],
+ "action": {
+ "default_popup": "index.html"
+ },
+ "web_accessible_resources": [
+ {
+ "resources": [
+ "wps.js"
+ ],
+ "matches": [
+ ""
+ ]
+ }
+ ]
+}
diff --git a/crx/sw.js b/crx/sw.js
index fe468cf..0dd5f81 100644
--- a/crx/sw.js
+++ b/crx/sw.js
@@ -1,52 +1,52 @@
-// function injectedFunction(color) {
-// document.body.style.backgroundColor = color;
-// }
-
-
-// chrome.runtime.onMessage.addListener(async ({ name, options }) => {
-// if (name === 'addRecord') {
-// console.log('Hello World!');
-
-// // get active tab
-// // const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
-// // chrome.scripting.executeScript({
-// // target: { tabId: tab.id },
-// // func: injectedFunction,
-// // args: ["orange"],
-// // });
-
-// const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
-// const response = await chrome.tabs.sendMessage(tab.id, { greeting: "hello" });
-// // do something with response here, not outside the function
-// console.log(response);
-
-// }
-// });
-
-let port;
-
-function sendMessage(message) {
- if (!port) {
- // this will run the first time to launch the native host, and save the connection to that instance in the port
- port = chrome.runtime.connectNative('com.woni.chrome.botext');
- }
- // Convert the message to a Uint8Array.
- var encoder = new TextEncoder();
- var messageBytes = encoder.encode(message);
- // Send the message length as a 32-bit integer.
- var buffer = new ArrayBuffer(4);
- var view = new DataView(buffer);
- view.setUint32(0, messageBytes.length, true);
- port.postMessage(buffer);
-
- // Send the message content.
- port.postMessage(messageBytes);
-}
-
-
-
-
-
-sendMessage('message 1');
-sendMessage('message 2');
-sendMessage('message 3');
+// function injectedFunction(color) {
+// document.body.style.backgroundColor = color;
+// }
+
+
+// chrome.runtime.onMessage.addListener(async ({ name, options }) => {
+// if (name === 'addRecord') {
+// console.log('Hello World!');
+
+// // get active tab
+// // const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
+// // chrome.scripting.executeScript({
+// // target: { tabId: tab.id },
+// // func: injectedFunction,
+// // args: ["orange"],
+// // });
+
+// const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
+// const response = await chrome.tabs.sendMessage(tab.id, { greeting: "hello" });
+// // do something with response here, not outside the function
+// console.log(response);
+
+// }
+// });
+
+let port;
+
+function sendMessage(message) {
+ if (!port) {
+ // this will run the first time to launch the native host, and save the connection to that instance in the port
+ port = chrome.runtime.connectNative('com.woni.chrome.botext');
+ }
+ // Convert the message to a Uint8Array.
+ var encoder = new TextEncoder();
+ var messageBytes = encoder.encode(message);
+ // Send the message length as a 32-bit integer.
+ var buffer = new ArrayBuffer(4);
+ var view = new DataView(buffer);
+ view.setUint32(0, messageBytes.length, true);
+ port.postMessage(buffer);
+
+ // Send the message content.
+ port.postMessage(messageBytes);
+}
+
+
+
+
+
+sendMessage('message 1');
+sendMessage('message 2');
+sendMessage('message 3');
diff --git a/crx/wps.js b/crx/wps.js
index 91dca1c..faf2a3f 100644
--- a/crx/wps.js
+++ b/crx/wps.js
@@ -1,69 +1,69 @@
-
-async function createApp() {
- for (let i = 0; i < 10; i++) {
-
- try {
- window.$dbSheet = {};
- // set dbsheet app 属性 为 WPSOpenApi.Application;
- window.$dbSheet.app = WPSOpenApi.Application;
-
- $dbSheet.createRecords = () => {
- const records = $dbSheet.app.Record.CreateRecords({
- SheetId: 1,
- Records: [{ fields: { "名称": "demo", "数量": 1, "日期": "2022/1/1", "状态": "未开始" } }]
- });
- }
-
- $dbSheet.deleteRecords = async () => {
-
- const records = await $dbSheet.app.Record.GetRecords({ SheetId: 1 })
- const deleteRcecordId = records.records[0].id
- const result = $dbSheet.app.Record.DeleteRecords({
- SheetId: 1,
- RecordIds: [deleteRcecordId]
- })
- }
- console.log(i);
- } catch (error) {
- // sleep 1s
- await new Promise(resolve => setTimeout(resolve, 1000));
- console.log(i, error);
- }
- }
-}
-
-// 异步执行 createApp
-
-createApp().then(() => { });
-
-window.addEventListener('message', (event) => {
- if (event.source === window && event.data.func === 'addRecord') {
- // console.log('[Demo] receive', event.data);
- addRecordOnMessage();
- }
-
- if (event.source === window && event.data.func === 'deleteRecord') {
- // console.log('[Demo] receive', event.data);
- deleteRecordOnMessage();
- }
-});
-
-
-async function addRecordOnMessage() {
- $dbSheet.createRecords();
- window.postMessage({ msg: 'add record by inject script', from: 'inject-script' });
-}
-
-
-async function deleteRecordOnMessage() {
- await $dbSheet.deleteRecords();
- window.postMessage({ msg: 'delete record by inject script', from: 'inject-script' });
-}
-
-
-async function sendMsgToContentScript() {
- console.log('[Demo] ==============================================');
- console.log('[Demo] Test send message from inject script to content script');
- $dbSheet.createRecords();
- window.postMessage({ msg: 'ping from inject script', from: 'inject-script' });
-}
+
+async function createApp() {
+ for (let i = 0; i < 10; i++) {
+
+ try {
+ window.$dbSheet = {};
+ // set dbsheet app 属性 为 WPSOpenApi.Application;
+ window.$dbSheet.app = WPSOpenApi.Application;
+
+ $dbSheet.createRecords = () => {
+ const records = $dbSheet.app.Record.CreateRecords({
+ SheetId: 1,
+ Records: [{ fields: { "名称": "demo", "数量": 1, "日期": "2022/1/1", "状态": "未开始" } }]
+ });
+ }
+
+ $dbSheet.deleteRecords = async () => {
+
+ const records = await $dbSheet.app.Record.GetRecords({ SheetId: 1 })
+ const deleteRcecordId = records.records[0].id
+ const result = $dbSheet.app.Record.DeleteRecords({
+ SheetId: 1,
+ RecordIds: [deleteRcecordId]
+ })
+ }
+ console.log(i);
+ } catch (error) {
+ // sleep 1s
+ await new Promise(resolve => setTimeout(resolve, 1000));
+ console.log(i, error);
+ }
+ }
+}
+
+// 异步执行 createApp
+
+createApp().then(() => { });
+
+window.addEventListener('message', (event) => {
+ if (event.source === window && event.data.func === 'addRecord') {
+ // console.log('[Demo] receive', event.data);
+ addRecordOnMessage();
+ }
+
+ if (event.source === window && event.data.func === 'deleteRecord') {
+ // console.log('[Demo] receive', event.data);
+ deleteRecordOnMessage();
+ }
+});
+
+
+async function addRecordOnMessage() {
+ $dbSheet.createRecords();
+ window.postMessage({ msg: 'add record by inject script', from: 'inject-script' });
+}
+
+
+async function deleteRecordOnMessage() {
+ await $dbSheet.deleteRecords();
+ window.postMessage({ msg: 'delete record by inject script', from: 'inject-script' });
+}
+
+
+async function sendMsgToContentScript() {
+ console.log('[Demo] ==============================================');
+ console.log('[Demo] Test send message from inject script to content script');
+ $dbSheet.createRecords();
+ window.postMessage({ msg: 'ping from inject script', from: 'inject-script' });
+}
diff --git a/docs/botext-init.md b/docs/botext-init.md
index 78922d5..0657201 100644
--- a/docs/botext-init.md
+++ b/docs/botext-init.md
@@ -1,6 +1,6 @@
-1. 注册表
-
-REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.google.chrome.botext" /ve /t REG_SZ /d "%~dp0com.google.chrome.botext.json" /f
-
-com.woni.chrome.botext
-
+1. 注册表
+
+REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.google.chrome.botext" /ve /t REG_SZ /d "%~dp0com.google.chrome.botext.json" /f
+
+com.woni.chrome.botext
+
diff --git a/docs/install.md b/docs/install.md
index acf6240..58da04d 100644
--- a/docs/install.md
+++ b/docs/install.md
@@ -1,11 +1,11 @@
-安装python模块自动运行脚本
-
-1. 修改注册表
-2. 拷贝文件至目标目录
-3. 安装插件
-
-
-
-
-
-
+安装python模块自动运行脚本
+
+1. 修改注册表
+2. 拷贝文件至目标目录
+3. 安装插件
+
+
+
+
+
+
diff --git a/poetry.lock b/poetry.lock
index 221a425..5b48e71 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,73 +1,73 @@
-# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand.
-
-[[package]]
-name = "cython"
-version = "3.0.2"
-description = "The Cython compiler for writing C extensions in the Python language."
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-files = [
- {file = "Cython-3.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8ccb91d2254e34724f1541b2a6fcdfacdb88284185b0097ae84e0ddf476c7a38"},
- {file = "Cython-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c298b1589205ecaaed0457ad05e0c8a43e7db2053607f48ed4a899cb6aa114df"},
- {file = "Cython-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e825e682cef76d0c33384f38b56b7e87c76152482a914dfc78faed6ff66ce05a"},
- {file = "Cython-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:77ec0134fc1b10aebef2013936a91c07bff2498ec283bc2eca099ee0cb94d12e"},
- {file = "Cython-3.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c90eeb94395315e65fd758a2f86b92904fce7b50060b4d45a878ef6767f9276e"},
- {file = "Cython-3.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:38085523fa7a299638d051ae08144222785639882f6291bd275c0b12db1034ff"},
- {file = "Cython-3.0.2-cp310-cp310-win32.whl", hash = "sha256:b032cb0c69082f0665b2c5fb416d041157062f1538336d0edf823b9ee500e39c"},
- {file = "Cython-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:067b2b9eb487bd61367b296f11b7c1c70a084b3eb7d5a572f607cd1fc5ca5586"},
- {file = "Cython-3.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:213ff9f95de319e54b520bf31edd6aa7a1fa4fbf617c2beb0f92362595e6476a"},
- {file = "Cython-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bebbca13078125a35937966137af4bd0300a0c66fd7ae4ce36adc049b13bdf3"},
- {file = "Cython-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5e5587128e8c2423aefcffa4ded4ddf60d44898938fbb7c0f236636a750a94f"},
- {file = "Cython-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78e2853d484643c6b7ac3bdb48392753442da1c71b689468fa3176b619bebe54"},
- {file = "Cython-3.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c5e722732e9aa9bde667ed6d87525234823eb7766ca234cfb19d7e0c095a2ef4"},
- {file = "Cython-3.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:989787fc24a95100a26918b6577d06e15a8868a3ed267009c5cfcf1a906179ac"},
- {file = "Cython-3.0.2-cp311-cp311-win32.whl", hash = "sha256:d21801981db44b7e9f9768f121317946461d56b51de1e6eff3c42e8914048696"},
- {file = "Cython-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:809617cf4825b2138ce0ec827e1f28e39668743c81ac8286373f8d148c05f088"},
- {file = "Cython-3.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5682293d344b7dbad97ce6eceb9e887aca6e53499709db9da726ca3424e5559d"},
- {file = "Cython-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e08ff5da5f5b969639784b1bffcd880a0c0f048d182aed7cba9945ee8b367c2"},
- {file = "Cython-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8850269ff59f77a1629e26d0576701925360d732011d6d3516ccdc5b2c2bc310"},
- {file = "Cython-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:550b3fbe9b3c555b44ded934f4822f9fcc04dfcee512167ebcbbd370ccede20e"},
- {file = "Cython-3.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4db017b104f47b1185237702f6ed2651839c8124614683efa7c489f3fa4e19d9"},
- {file = "Cython-3.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:75a2395cc7b78cff59be6e9b7f92bbb5d7b8d25203f6d3fb6f72bdb7d3f49777"},
- {file = "Cython-3.0.2-cp312-cp312-win32.whl", hash = "sha256:786b6034a91e886116bb562fe42f8bf0f97c3e00c02e56791d02675959ed65b1"},
- {file = "Cython-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc9d173ab8b167cae674f6deed8c65ba816574797a2bd6d8aa623277d1fa81ca"},
- {file = "Cython-3.0.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8948504338d7a140ce588333177dcabf0743a68dbc83b0174f214f5b959634d5"},
- {file = "Cython-3.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a51efba0e136b2af358e5a347bae09678b17460c35cf1eab24f0476820348991"},
- {file = "Cython-3.0.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05cb2a73810f045d328b7579cf98f550a9e601df5e282d1fea0512d8ad589011"},
- {file = "Cython-3.0.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22ba78e48bdb65977928ecb275ac8c82df7b0eefa075078a1363a5af4606b42e"},
- {file = "Cython-3.0.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:302281b927409b3e0ef8cd9251eab782cf1acd2578eab305519fbae5d184b7e9"},
- {file = "Cython-3.0.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:a1c3675394b81024aaf56e4f53c2b4f81d9a116c7049e9d4706f810899c9134e"},
- {file = "Cython-3.0.2-cp36-cp36m-win32.whl", hash = "sha256:34f7b014ebce5d325c8084e396c81cdafbd8d82be56780dffe6b67b28c891f1b"},
- {file = "Cython-3.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:477cd3549597f09a1608da7b05e16ba641e9aedd171b868533a5a07790ed886f"},
- {file = "Cython-3.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a49dde9f9e29ea82f29aaf3bb1a270b6eb90b75d627c7ff2f5dd3764540ae646"},
- {file = "Cython-3.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc1c8013fad0933f5201186eccc5f2be223cafd6a8dcd586d3f7bb6ba84dc845"},
- {file = "Cython-3.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b75e9c9d7ad7c9dd85d45241d1d4e3c5f66079c1f84eec91689c26d98bc3349"},
- {file = "Cython-3.0.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f43c4d3ecd9e3b8b7afe834e519f55cf4249b1088f96d11b96f02c55cbaeff7"},
- {file = "Cython-3.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:dab6a923e21e212aa3dc6dde9b22a190f5d7c449315a94e57ddc019ea74a979b"},
- {file = "Cython-3.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ae453cfa933b919c0a19d2cc5dc9fb28486268e95dc2ab7a11ab7f99cf8c3883"},
- {file = "Cython-3.0.2-cp37-cp37m-win32.whl", hash = "sha256:b1f023d36a3829069ed11017c670128be3f135a9c17bd64c35d3b3442243b05c"},
- {file = "Cython-3.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:011c4e0b75baee1843334562487eb4fbc0c59ddb2cc32a978b972a81eedcbdcc"},
- {file = "Cython-3.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:832bbee87bca760efeae248ddf19ccd77f9a2355cb6f8a64f20cc377e56957b3"},
- {file = "Cython-3.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fe806d154b6b7f0ab746dac36c022889e2e7cf47546ff9afdc29a62cfa692d0"},
- {file = "Cython-3.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e486331a29e7700b1ad5f4f753bef483c81412a5e64a873df46d6cb66f9a65de"},
- {file = "Cython-3.0.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54d41a1dfbaab74449873e7f8e6cd4239850fe7a50f7f784dd99a560927f3bac"},
- {file = "Cython-3.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4dca13c86d6cd523c7d8bbf8db1b2bbf8faedd0addedb229158d8015ad1819e1"},
- {file = "Cython-3.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:10cbfb37f31938371a6213cc8b5459c639954aed053efeded3c012d4c5915db9"},
- {file = "Cython-3.0.2-cp38-cp38-win32.whl", hash = "sha256:e663c237579c033deaa2cb362b74651da7712f56e441c11382510a8c4c4f2dd7"},
- {file = "Cython-3.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:2f84bd6cefa5130750c492038170c44f1cbd6f42e9ed85e168fd9cb453f85160"},
- {file = "Cython-3.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f37e4287f520f3748a06ad5eaae09ba4ac68f52e155d70de5f75780d83575c43"},
- {file = "Cython-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd30826ca8b27b2955a63c8ffe8aacc9f0779582b4bd154cf7b441ac10dae2cb"},
- {file = "Cython-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08d67c7225a09eeb77e090c8d4f60677165b052ccf76e3a57d8237064e5c2de2"},
- {file = "Cython-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e625eec8c5c9a8cb062a318b257cc469d301bed952c7daf86e38bbd3afe7c91"},
- {file = "Cython-3.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1b12a8f23270675b537d1c3b988f845bea4bbcc66ae0468857f5ede0526d4522"},
- {file = "Cython-3.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:62dd78afdf748a58dae9c9b9c42a1519ae30787b28ce5f84a0e1bb54144142ca"},
- {file = "Cython-3.0.2-cp39-cp39-win32.whl", hash = "sha256:d0d0cc4ecc05f41c5e02af14ac0083552d22efed976f79eb7bade55fed63b25d"},
- {file = "Cython-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:147cc1d3dda8b06de9d86df5e59cdf15f0a522620168b7349a5ec88b48104d7d"},
- {file = "Cython-3.0.2-py2.py3-none-any.whl", hash = "sha256:8f1c9e4b8e413da211dd7942440cf410ff0eafb081309e04e81f4fafbb146bf2"},
- {file = "Cython-3.0.2.tar.gz", hash = "sha256:9594818dca8bb22ae6580c5222da2bc5cc32334350bd2d294a00d8669bcc61b5"},
-]
-
-[metadata]
-lock-version = "2.0"
-python-versions = "^3.11"
-content-hash = "985e70bd8daa7e47f02a146f5788cf4411ff36da7c58f474bc2a9bb8d0eb2481"
+# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand.
+
+[[package]]
+name = "cython"
+version = "3.0.2"
+description = "The Cython compiler for writing C extensions in the Python language."
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+files = [
+ {file = "Cython-3.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8ccb91d2254e34724f1541b2a6fcdfacdb88284185b0097ae84e0ddf476c7a38"},
+ {file = "Cython-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c298b1589205ecaaed0457ad05e0c8a43e7db2053607f48ed4a899cb6aa114df"},
+ {file = "Cython-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e825e682cef76d0c33384f38b56b7e87c76152482a914dfc78faed6ff66ce05a"},
+ {file = "Cython-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:77ec0134fc1b10aebef2013936a91c07bff2498ec283bc2eca099ee0cb94d12e"},
+ {file = "Cython-3.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c90eeb94395315e65fd758a2f86b92904fce7b50060b4d45a878ef6767f9276e"},
+ {file = "Cython-3.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:38085523fa7a299638d051ae08144222785639882f6291bd275c0b12db1034ff"},
+ {file = "Cython-3.0.2-cp310-cp310-win32.whl", hash = "sha256:b032cb0c69082f0665b2c5fb416d041157062f1538336d0edf823b9ee500e39c"},
+ {file = "Cython-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:067b2b9eb487bd61367b296f11b7c1c70a084b3eb7d5a572f607cd1fc5ca5586"},
+ {file = "Cython-3.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:213ff9f95de319e54b520bf31edd6aa7a1fa4fbf617c2beb0f92362595e6476a"},
+ {file = "Cython-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bebbca13078125a35937966137af4bd0300a0c66fd7ae4ce36adc049b13bdf3"},
+ {file = "Cython-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5e5587128e8c2423aefcffa4ded4ddf60d44898938fbb7c0f236636a750a94f"},
+ {file = "Cython-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78e2853d484643c6b7ac3bdb48392753442da1c71b689468fa3176b619bebe54"},
+ {file = "Cython-3.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c5e722732e9aa9bde667ed6d87525234823eb7766ca234cfb19d7e0c095a2ef4"},
+ {file = "Cython-3.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:989787fc24a95100a26918b6577d06e15a8868a3ed267009c5cfcf1a906179ac"},
+ {file = "Cython-3.0.2-cp311-cp311-win32.whl", hash = "sha256:d21801981db44b7e9f9768f121317946461d56b51de1e6eff3c42e8914048696"},
+ {file = "Cython-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:809617cf4825b2138ce0ec827e1f28e39668743c81ac8286373f8d148c05f088"},
+ {file = "Cython-3.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5682293d344b7dbad97ce6eceb9e887aca6e53499709db9da726ca3424e5559d"},
+ {file = "Cython-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e08ff5da5f5b969639784b1bffcd880a0c0f048d182aed7cba9945ee8b367c2"},
+ {file = "Cython-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8850269ff59f77a1629e26d0576701925360d732011d6d3516ccdc5b2c2bc310"},
+ {file = "Cython-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:550b3fbe9b3c555b44ded934f4822f9fcc04dfcee512167ebcbbd370ccede20e"},
+ {file = "Cython-3.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4db017b104f47b1185237702f6ed2651839c8124614683efa7c489f3fa4e19d9"},
+ {file = "Cython-3.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:75a2395cc7b78cff59be6e9b7f92bbb5d7b8d25203f6d3fb6f72bdb7d3f49777"},
+ {file = "Cython-3.0.2-cp312-cp312-win32.whl", hash = "sha256:786b6034a91e886116bb562fe42f8bf0f97c3e00c02e56791d02675959ed65b1"},
+ {file = "Cython-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc9d173ab8b167cae674f6deed8c65ba816574797a2bd6d8aa623277d1fa81ca"},
+ {file = "Cython-3.0.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8948504338d7a140ce588333177dcabf0743a68dbc83b0174f214f5b959634d5"},
+ {file = "Cython-3.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a51efba0e136b2af358e5a347bae09678b17460c35cf1eab24f0476820348991"},
+ {file = "Cython-3.0.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05cb2a73810f045d328b7579cf98f550a9e601df5e282d1fea0512d8ad589011"},
+ {file = "Cython-3.0.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22ba78e48bdb65977928ecb275ac8c82df7b0eefa075078a1363a5af4606b42e"},
+ {file = "Cython-3.0.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:302281b927409b3e0ef8cd9251eab782cf1acd2578eab305519fbae5d184b7e9"},
+ {file = "Cython-3.0.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:a1c3675394b81024aaf56e4f53c2b4f81d9a116c7049e9d4706f810899c9134e"},
+ {file = "Cython-3.0.2-cp36-cp36m-win32.whl", hash = "sha256:34f7b014ebce5d325c8084e396c81cdafbd8d82be56780dffe6b67b28c891f1b"},
+ {file = "Cython-3.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:477cd3549597f09a1608da7b05e16ba641e9aedd171b868533a5a07790ed886f"},
+ {file = "Cython-3.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a49dde9f9e29ea82f29aaf3bb1a270b6eb90b75d627c7ff2f5dd3764540ae646"},
+ {file = "Cython-3.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc1c8013fad0933f5201186eccc5f2be223cafd6a8dcd586d3f7bb6ba84dc845"},
+ {file = "Cython-3.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b75e9c9d7ad7c9dd85d45241d1d4e3c5f66079c1f84eec91689c26d98bc3349"},
+ {file = "Cython-3.0.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f43c4d3ecd9e3b8b7afe834e519f55cf4249b1088f96d11b96f02c55cbaeff7"},
+ {file = "Cython-3.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:dab6a923e21e212aa3dc6dde9b22a190f5d7c449315a94e57ddc019ea74a979b"},
+ {file = "Cython-3.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ae453cfa933b919c0a19d2cc5dc9fb28486268e95dc2ab7a11ab7f99cf8c3883"},
+ {file = "Cython-3.0.2-cp37-cp37m-win32.whl", hash = "sha256:b1f023d36a3829069ed11017c670128be3f135a9c17bd64c35d3b3442243b05c"},
+ {file = "Cython-3.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:011c4e0b75baee1843334562487eb4fbc0c59ddb2cc32a978b972a81eedcbdcc"},
+ {file = "Cython-3.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:832bbee87bca760efeae248ddf19ccd77f9a2355cb6f8a64f20cc377e56957b3"},
+ {file = "Cython-3.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fe806d154b6b7f0ab746dac36c022889e2e7cf47546ff9afdc29a62cfa692d0"},
+ {file = "Cython-3.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e486331a29e7700b1ad5f4f753bef483c81412a5e64a873df46d6cb66f9a65de"},
+ {file = "Cython-3.0.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54d41a1dfbaab74449873e7f8e6cd4239850fe7a50f7f784dd99a560927f3bac"},
+ {file = "Cython-3.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4dca13c86d6cd523c7d8bbf8db1b2bbf8faedd0addedb229158d8015ad1819e1"},
+ {file = "Cython-3.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:10cbfb37f31938371a6213cc8b5459c639954aed053efeded3c012d4c5915db9"},
+ {file = "Cython-3.0.2-cp38-cp38-win32.whl", hash = "sha256:e663c237579c033deaa2cb362b74651da7712f56e441c11382510a8c4c4f2dd7"},
+ {file = "Cython-3.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:2f84bd6cefa5130750c492038170c44f1cbd6f42e9ed85e168fd9cb453f85160"},
+ {file = "Cython-3.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f37e4287f520f3748a06ad5eaae09ba4ac68f52e155d70de5f75780d83575c43"},
+ {file = "Cython-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd30826ca8b27b2955a63c8ffe8aacc9f0779582b4bd154cf7b441ac10dae2cb"},
+ {file = "Cython-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08d67c7225a09eeb77e090c8d4f60677165b052ccf76e3a57d8237064e5c2de2"},
+ {file = "Cython-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e625eec8c5c9a8cb062a318b257cc469d301bed952c7daf86e38bbd3afe7c91"},
+ {file = "Cython-3.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1b12a8f23270675b537d1c3b988f845bea4bbcc66ae0468857f5ede0526d4522"},
+ {file = "Cython-3.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:62dd78afdf748a58dae9c9b9c42a1519ae30787b28ce5f84a0e1bb54144142ca"},
+ {file = "Cython-3.0.2-cp39-cp39-win32.whl", hash = "sha256:d0d0cc4ecc05f41c5e02af14ac0083552d22efed976f79eb7bade55fed63b25d"},
+ {file = "Cython-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:147cc1d3dda8b06de9d86df5e59cdf15f0a522620168b7349a5ec88b48104d7d"},
+ {file = "Cython-3.0.2-py2.py3-none-any.whl", hash = "sha256:8f1c9e4b8e413da211dd7942440cf410ff0eafb081309e04e81f4fafbb146bf2"},
+ {file = "Cython-3.0.2.tar.gz", hash = "sha256:9594818dca8bb22ae6580c5222da2bc5cc32334350bd2d294a00d8669bcc61b5"},
+]
+
+[metadata]
+lock-version = "2.0"
+python-versions = "^3.11"
+content-hash = "985e70bd8daa7e47f02a146f5788cf4411ff36da7c58f474bc2a9bb8d0eb2481"
diff --git a/publish-addon.sh b/publish-addon.sh
new file mode 100644
index 0000000..7dc680c
--- /dev/null
+++ b/publish-addon.sh
@@ -0,0 +1,82 @@
+#!/bin/bash
+
+client_id="ff7d5a3b-a020-46f5-8d97-b996c3c64f0e"
+client_secret="5B~8Q~xrpV1-eBkZIPaNL0r6apMbWaFMtAoaSdz6"
+product_id="f65aed0e-55f6-4b68-9c1b-60bb7000e1e4"
+file_name="crx.zip"
+
+zip $file_name crx/*
+echo "Zip file created."
+
+# get token
+token_response=$(curl -s -X POST \
+ -H "Content-Type: application/x-www-form-urlencoded" \
+ -d "client_id=${client_id}" \
+ -d "scope=https://api.addons.microsoftedge.microsoft.com/.default" \
+ -d "client_secret=${client_secret}" \
+ -d "grant_type=client_credentials" \
+ https://login.microsoftonline.com/5c9eedce-81bc-42f3-8823-48ba6258b391/oauth2/v2.0/token)
+
+token=$(echo $token_response | jq -r '.access_token')
+
+echo "get token success"
+# echo token
+
+# Upload zip file
+upload_response=$(curl -s -D - \
+ -H "Authorization: Bearer $token" \
+ -H "Content-Type: application/zip" \
+ -X POST \
+ -T $file_name \
+ https://api.addons.microsoftedge.microsoft.com/v1/products/$product_id/submissions/draft/package)
+
+# Get Location
+operation_id=$(echo "$upload_response" | grep -Fi Location | awk '{print $2}' | tr -d '\r')
+# echo $operation_id
+
+check_response=$(curl -s \
+ -H "Authorization: Bearer $token" \
+ -X GET \
+ https://api.addons.microsoftedge.microsoft.com/v1/products/$product_id/submissions/draft/package/operations/$operation_id)
+
+# echo $check_response
+
+errorCode=$(echo $check_response | jq -r '.errorCode')
+
+if [ "$errorCode" = "null" ]; then
+ echo "Upload successful."
+else
+ echo "Upload failed. Error code: $errorCode"
+ errors=$(echo $check_response | jq -r '.errors')
+ echo "Error details: $errors"
+ exit 1
+fi
+
+publish_response=$(curl -s -D - \
+ -H "Authorization: Bearer $token" \
+ -X POST \
+ -d '{ "notes"="Add some features" }' \
+ https://api.addons.microsoftedge.microsoft.com/v1/products/$product_id/submissions)
+
+# echo $publish_response
+
+operation_id=$(echo "$publish_response" | grep -Fi Location | awk '{print $2}' | tr -d '\r')
+# echo $operation_id
+
+check_publish_response=$(curl -s \
+ -H "Authorization: Bearer $token" \
+ https://api.addons.microsoftedge.microsoft.com/v1/products/$product_id/submissions/operations/{$operation_id})
+
+# echo $check_publish_response
+
+# 使用 jq 提取 errorCode
+errorCode=$(echo $check_publish_response | jq -r '.errorCode')
+
+# 检查 errorCode 是否为 null
+if [ "$errorCode" = "null" ]; then
+ echo "Submit successful."
+else
+ echo "Operation failed. Error code: $errorCode"
+ errors=$(echo $check_publish_response | jq -r '.message')
+ echo "Error details: $errors"
+fi
diff --git a/pyproject.toml b/pyproject.toml
index 6273d47..a460ad2 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,22 +1,22 @@
-[tool.poetry]
-name = "botext"
-version = "0.1.0"
-description = ""
-authors = ["woni <320753691@qq.com>"]
-readme = "README.md"
-
-[tool.poetry.dependencies]
-python = "^3.11"
-
-
-[tool.poetry.group.dev.dependencies]
-cython = "^3.0.2"
-
-[build-system]
-requires = ["poetry-core"]
-build-backend = "poetry.core.masonry.api"
-
-
-
-[tool.poetry.scripts]
-install = "botext.install:main"
+[tool.poetry]
+name = "botext"
+version = "0.1.0"
+description = ""
+authors = ["woni <320753691@qq.com>"]
+readme = "README.md"
+
+[tool.poetry.dependencies]
+python = "^3.11"
+
+
+[tool.poetry.group.dev.dependencies]
+cython = "^3.0.2"
+
+[build-system]
+requires = ["poetry-core"]
+build-backend = "poetry.core.masonry.api"
+
+
+
+[tool.poetry.scripts]
+install = "botext.install:main"