diff --git a/README.md b/README.md index 4e8fd81de..50d7442e8 100755 --- a/README.md +++ b/README.md @@ -527,9 +527,12 @@ Plugin capabilities include: - Reading files - Appending to files - Writing files -- Deleting files +- Deleting files and directories - Listing files and directories - Creating directories +- Downloading files +- Copying files and directories +- Moving (renaming) files and directories If a file being created (with the same name) already exists, a prefix including the date and time is added to the file name. @@ -537,31 +540,51 @@ If a file being created (with the same name) already exists, a prefix including - `Enable: Read file` *cmd_read_file* -Allow `read_file` command. *Default:* `True` +Allows `read_file` command. *Default:* `True` - `Enable: Append to file` *cmd_append_file* -Allow `append_file` command. *Default:* `True` +Allows `append_file` command. *Default:* `True` - `Enable: Save file` *cmd_save_file* -Allow `save_file` command. *Default:* `True` +Allows `save_file` command. *Default:* `True` - `Enable: Delete file` *cmd_delete_file* -Allow `delete_file` command. *Default:* `True` +Allows `delete_file` command. *Default:* `True` - `Enable: List files (ls)` *cmd_list_files* -Allow `list_files` command. *Default:* `True` +Allows `list_files` command. *Default:* `True` - `Enable: List directories (ls)` *cmd_list_dirs* -Allow `list_dirs` command. *Default:* `True` +Allows `list_dirs` command. *Default:* `True` - `Enable: Directory creation (mkdir)` *cmd_mkdir* -Allow `mkdir` command. *Default:* `True` +Allows `mkdir` command. *Default:* `True` + +- `Enable: Downloading files` *cmd_download_file* + +Allows `download_file` command. *Default:* `True` + +- `Enable: Removing directories` *cmd_rmdir* + +Allows `rmdir` command. *Default:* `True` + +- `Enable: Copying files` *cmd_copy_file* + +Allows `copy_file` command. *Default:* `True` + +- `Enable: Copying directories (recursive)` *cmd_copy_dir* + +Allows `copy_dir` command. *Default:* `True` + +- `Enable: Move files and directories (rename)` *cmd_move* + +Allows `move` command. *Default:* `True` ## Command: Code Interpreter @@ -582,15 +605,15 @@ Python command template (use {filename} as path to file placeholder). *Default:* - `Enable: Python Code Generate and Execute` *cmd_code_execute* -Allow Python code execution (generate and execute from file). *Default:* `True` +Allows Python code execution (generate and execute from file). *Default:* `True` - `Enable: Python Code Execute (File)` *cmd_code_execute_file* -Allow Python code execution from existing file. *Default:* `True` +Allows Python code execution from existing file. *Default:* `True` - `Enable: System Command Execute` *cmd_sys_exec* -Allow system commands execution. *Default:* `True` +Allows system commands execution. *Default:* `True` ## Command: Custom Commands @@ -1021,7 +1044,8 @@ may consume additional tokens that are not displayed in the main window. ## 2.0.9 (2023-12-09) -- Added `Custom Commands` feature; it allows to easily create and execute custom commands +- Added `Command: Custom Commands` feature; plugin allows to easily create and execute custom commands +- Added new features to `Command: Files I/O`: downloading files, copying files and dirs, moving files and dirs ## 2.0.8 (2023-12-08) @@ -1136,7 +1160,7 @@ New features in version 2.0.0: **PyPI:** -**Author:** Marcin Szczygliński (Poland, UE) +**Author:** Marcin Szczygliński (Poland, EU) **Contact:** diff --git a/docs/source/credits.rst b/docs/source/credits.rst index 8c6b9eab5..f41ac52dd 100644 --- a/docs/source/credits.rst +++ b/docs/source/credits.rst @@ -11,7 +11,7 @@ https://github.com/szczyglis-dev/py-gpt https://pypi.org/project/pygpt-net **Author:** -Marcin Szczygliński (Poland, UE) +Marcin Szczygliński (Poland, EU) **Contact:** info@pygpt.net diff --git a/docs/source/plugins_list.rst b/docs/source/plugins_list.rst index 9fefd2847..3a38216e2 100644 --- a/docs/source/plugins_list.rst +++ b/docs/source/plugins_list.rst @@ -11,9 +11,12 @@ Plugin capabilities include: * Reading files * Appending to files * Writing files -* Deleting files +* Deleting files and directories * Listing files and directories * Creating directories +* Downloading files +* Copying files and directories +* Moving (renaming) files and directories If a file being created (with the same name) already exists, a prefix including the date and time is added to the file name. @@ -21,31 +24,51 @@ If a file being created (with the same name) already exists, a prefix including - ``Enable: Read file`` *cmd_read_file* -Allow `read_file` command. *Default:* `True` +Allows `read_file` command. *Default:* `True` - ``Enable: Append to file`` *cmd_append_file* -Allow `append_file` command. *Default:* `True` +Allows `append_file` command. *Default:* `True` - ``Enable: Save file`` *cmd_save_file* -Allow `save_file` command. *Default:* `True` +Allows `save_file` command. *Default:* `True` - ``Enable: Delete file`` *cmd_delete_file* -Allow `delete_file` command. *Default:* `True` +Allows `delete_file` command. *Default:* `True` - ``Enable: List files (ls)`` *cmd_list_files* -Allow `list_files` command. *Default:* `True` +Allows `list_files` command. *Default:* `True` - ``Enable: List directories (ls)`` *cmd_list_dirs* -Allow `list_dirs` command. *Default:* `True` +Allows `list_dirs` command. *Default:* `True` - ``Enable: Directory creation (mkdir)`` *cmd_mkdir* -Allow `mkdir` command. *Default:* `True` +Allows `mkdir` command. *Default:* `True` + +- ``Enable: Downloading files`` *cmd_download_file* + +Allows `download_file` command. *Default:* `True` + +- ``Enable: Removing directories`` *cmd_rmdir* + +Allows `rmdir` command. *Default:* `True` + +- ``Enable: Copying files`` *cmd_copy_file* + +Allows `copy_file` command. *Default:* `True` + +- ``Enable: Copying directories (recursive)`` *cmd_copy_dir* + +Allows `copy_dir` command. *Default:* `True` + +- ``Enable: Move files and directories (rename)`` *cmd_move* + +Allows `move` command. *Default:* `True` Command: Code Interpreter @@ -67,15 +90,15 @@ Python command template (use {filename} as path to file placeholder). *Default:* - ``Enable: Python Code Generate and Execute`` *cmd_code_execute* -Allow Python code execution (generate and execute from file). *Default:* `True` +Allows Python code execution (generate and execute from file). *Default:* `True` - ``Enable: Python Code Execute (File)`` *cmd_code_execute_file* -Allow Python code execution from existing file. *Default:* `True` +Allows Python code execution from existing file. *Default:* `True` - ``Enable: System Command Execute`` *cmd_sys_exec* -Allow system commands execution. *Default:* `True` +Allows system commands execution. *Default:* `True` Command: Custom Commands @@ -128,7 +151,6 @@ You can connect predefined placeholders with your own params. - **params**: song_text, title - **cmd**: ``echo "{song_text}" > {_home}/{title}.txt`` - With the setup above, every time you ask GPT to generate a song for you and save it to the disk, it will: 1. Generate a song. diff --git a/pyproject.toml b/pyproject.toml index b20ad5cb5..457807f7a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "pygpt-net" -version = "2.0.8" +version = "2.0.9" description = "Desktop AI Assistant powered by GPT-4, GPT-4V, GPT-3, Whisper, TTS and DALL-E 3 with chatbot, assistant, text completion, vision and image generation, real-time internet access, commands and code execution, files upload and download and more" readme = "README.md" authors = [{ name = "Marcin Szczygliński", email = "info@pygpt.net" }] diff --git a/setup.py b/setup.py index 285e697b5..b5f1785a3 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -VERSION = '2.0.8' +VERSION = '2.0.9' DESCRIPTION = 'Desktop AI Assistant powered by GPT-4, GPT-4V, GPT-3, Whisper, TTS and DALL-E 3 with chatbot, assistant, text completion, ' \ 'vision and image generation, real-time internet access, commands and code execution, files upload and download and more' LONG_DESCRIPTION = 'Package containing a GPT-4, GPT-4V, GPT-3, Whisper, TTS and DALL-E 3 AI desktop assistant with chatbot, ' \ diff --git a/src/pygpt_net/CHANGELOG.txt b/src/pygpt_net/CHANGELOG.txt index e98a61d76..40c83ed6f 100755 --- a/src/pygpt_net/CHANGELOG.txt +++ b/src/pygpt_net/CHANGELOG.txt @@ -1,3 +1,8 @@ +2.0.9 (2023-12-09) + +- Added Command: Custom Commands feature; plugin allows to easily create and execute custom commands +- Added new features to Command: Files I/O: downloading files, copying files and dirs, moving files and dirs + 2.0.8 (2023-12-08) - Improved Web Search plugin diff --git a/src/pygpt_net/__init__.py b/src/pygpt_net/__init__.py index a943fbbae..2d9c062a1 100755 --- a/src/pygpt_net/__init__.py +++ b/src/pygpt_net/__init__.py @@ -13,8 +13,8 @@ __copyright__ = "Copyright 2023, Marcin Szczygliński" __credits__ = ["Marcin Szczygliński"] __license__ = "MIT" -__version__ = "2.0.8" -__build__ = "2023.12.08" +__version__ = "2.0.9" +__build__ = "2023.12.09" __maintainer__ = "Marcin Szczygliński" __github__ = "https://github.com/szczyglis-dev/py-gpt" __website__ = "https://pygpt.net" diff --git a/src/pygpt_net/core/plugin/cmd_code_interpreter/plugin.py b/src/pygpt_net/core/plugin/cmd_code_interpreter/plugin.py index fcfbca628..7c9cb6c99 100644 --- a/src/pygpt_net/core/plugin/cmd_code_interpreter/plugin.py +++ b/src/pygpt_net/core/plugin/cmd_code_interpreter/plugin.py @@ -38,7 +38,7 @@ def __init__(self): "type": "bool", "slider": False, "label": "Enable: Python Code Generate and Execute", - "description": "Allow Python code execution (generate and execute from file)", + "description": "Allows Python code execution (generate and execute from file)", "tooltip": "", "value": True, "min": None, @@ -50,7 +50,7 @@ def __init__(self): "type": "bool", "slider": False, "label": "Enable: Python Code Execute (File)", - "description": "Allow Python code execution from existing file", + "description": "Allows Python code execution from existing file", "tooltip": "", "value": True, "min": None, @@ -62,7 +62,7 @@ def __init__(self): "type": "bool", "slider": False, "label": "Enable: System Command Execute", - "description": "Allow system commands execution", + "description": "Allows system commands execution", "tooltip": "", "value": True, "min": None, @@ -70,34 +70,6 @@ def __init__(self): "multiplier": None, "step": None, } - self.options["tmp_list"] = { - "type": "dict", - "keys": { - "name": "text", - "desc": "text", - "cmd": "text", - }, - "slider": False, - "label": "tmp_list", - "description": "tmp_list", - "tooltip": "tmp_list", - "value": [ - { - "name": "item1", - "desc": "desc1", - "cmd": "cmd1", - }, - { - "name": "item2", - "desc": "desc2", - "cmd": "cmd2", - }, - ], - "min": None, - "max": None, - "multiplier": None, - "step": None, - } self.window = None self.order = 100 self.allowed_cmds = ["code_execute", "sys_exec"] @@ -194,77 +166,92 @@ def cmd(self, ctx, cmds): try: if item["cmd"] in self.allowed_cmds: if item["cmd"] == "code_execute_file" and self.is_cmd_allowed("code_execute_file"): - msg = "Executing Python file: {}".format(item["params"]['filename']) - print(msg) - path = os.path.join(self.window.config.path, 'output', item["params"]['filename']) + try: + msg = "Executing Python file: {}".format(item["params"]['filename']) + print(msg) + path = os.path.join(self.window.config.path, 'output', item["params"]['filename']) - # check if file exists - if not os.path.isfile(path): - msg = "File not found: {}".format(item["params"]['filename']) - ctx.results.append({"request": item, "result": "File not found"}) - ctx.reply = True # send result message - continue + # check if file exists + if not os.path.isfile(path): + msg = "File not found: {}".format(item["params"]['filename']) + ctx.results.append({"request": item, "result": "File not found"}) + ctx.reply = True # send result message + continue - # run code - cmd = self.options['python_cmd_tpl']['value'].format(filename=path) - print("Running command: {}".format(cmd)) - process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - stdout, stderr = process.communicate() - result = None - if stdout: - result = stdout.decode("utf-8") - if stderr: - result = stderr.decode("utf-8") - if result is None: - result = "No result (STDOUT/STDERR empty)" - ctx.results.append({"request": item, "result": result}) - print("Result (STDOUT): {}".format(result)) - ctx.reply = True # send result message + # run code + cmd = self.options['python_cmd_tpl']['value'].format(filename=path) + print("Running command: {}".format(cmd)) + process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + stdout, stderr = process.communicate() + result = None + if stdout: + result = stdout.decode("utf-8") + if stderr: + result = stderr.decode("utf-8") + if result is None: + result = "No result (STDOUT/STDERR empty)" + ctx.results.append({"request": item, "result": result}) + print("Result (STDOUT): {}".format(result)) + ctx.reply = True # send result message + except Exception as e: + ctx.results.append({"request": item, "result": "Error {}".format(e)}) + ctx.reply = True + print("Error: {}".format(e)) elif item["cmd"] == "code_execute" and self.is_cmd_allowed("code_execute"): - msg = "Saving Python file: {}".format(item["params"]['filename']) - print(msg) - path = os.path.join(self.window.config.path, 'output', item["params"]['filename']) - data = item["params"]['code'] - with open(path, 'w', encoding="utf-8") as file: - file.write(data) - file.close() + try: + msg = "Saving Python file: {}".format(item["params"]['filename']) + print(msg) + path = os.path.join(self.window.config.path, 'output', item["params"]['filename']) + data = item["params"]['code'] + with open(path, 'w', encoding="utf-8") as file: + file.write(data) + file.close() - # run code - cmd = self.options['python_cmd_tpl']['value'].format(filename=path) - print("Running command: {}".format(cmd)) - process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - stdout, stderr = process.communicate() - result = None - if stdout: - result = stdout.decode("utf-8") - if stderr: - result = stderr.decode("utf-8") - if result is None: - result = "No result (STDOUT/STDERR empty)" - ctx.results.append({"request": item, "result": result}) - print("Result (STDOUT): {}".format(result)) - ctx.reply = True # send result message + # run code + cmd = self.options['python_cmd_tpl']['value'].format(filename=path) + print("Running command: {}".format(cmd)) + process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + stdout, stderr = process.communicate() + result = None + if stdout: + result = stdout.decode("utf-8") + if stderr: + result = stderr.decode("utf-8") + if result is None: + result = "No result (STDOUT/STDERR empty)" + ctx.results.append({"request": item, "result": result}) + print("Result (STDOUT): {}".format(result)) + ctx.reply = True # send result message + except Exception as e: + ctx.results.append({"request": item, "result": "Error {}".format(e)}) + ctx.reply = True + print("Error: {}".format(e)) elif item["cmd"] == "sys_exec" and self.is_cmd_allowed("sys_exec"): - msg = "Executing system command: {}".format(item["params"]['command']) - print(msg) - print("Running command: {}".format(item["params"]['command'])) - process = subprocess.Popen(item["params"]['command'], shell=True, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - stdout, stderr = process.communicate() - result = None - if stdout: - result = stdout.decode("utf-8") - if stderr: - result = stderr.decode("utf-8") - if result is None: - result = "No result (STDOUT/STDERR empty)" - ctx.results.append({"request": item, "result": result}) - print("Result (STDOUT): {}".format(result)) - ctx.reply = True # send result message + try: + msg = "Executing system command: {}".format(item["params"]['command']) + print(msg) + print("Running command: {}".format(item["params"]['command'])) + process = subprocess.Popen(item["params"]['command'], shell=True, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + stdout, stderr = process.communicate() + result = None + if stdout: + result = stdout.decode("utf-8") + if stderr: + result = stderr.decode("utf-8") + if result is None: + result = "No result (STDOUT/STDERR empty)" + ctx.results.append({"request": item, "result": result}) + print("Result (STDOUT): {}".format(result)) + ctx.reply = True # send result message + except Exception as e: + ctx.results.append({"request": item, "result": "Error {}".format(e)}) + ctx.reply = True + print("Error: {}".format(e)) except Exception as e: ctx.results.append({"request": item, "result": "Error {}".format(e)}) ctx.reply = True diff --git a/src/pygpt_net/core/plugin/cmd_files/plugin.py b/src/pygpt_net/core/plugin/cmd_files/plugin.py index c70bfa4ad..aa4e69717 100644 --- a/src/pygpt_net/core/plugin/cmd_files/plugin.py +++ b/src/pygpt_net/core/plugin/cmd_files/plugin.py @@ -6,10 +6,12 @@ # GitHub: https://github.com/szczyglis-dev/py-gpt # # MIT License # # Created By : Marcin Szczygliński # -# Updated Date: 2023.12.08 18:00:00 # +# Updated Date: 2023.12.09 12:00:00 # # ================================================== # import os.path -from datetime import datetime +import shutil +import ssl +from urllib.request import Request, urlopen from ..base_plugin import BasePlugin @@ -105,9 +107,82 @@ def __init__(self): "multiplier": None, "step": None, } + self.options["cmd_download_file"] = { + "type": "bool", + "slider": False, + "label": "Enable: Downloading files", + "description": "Allows `download_file` command execution", + "tooltip": "", + "value": True, + "min": None, + "max": None, + "multiplier": None, + "step": None, + } + self.options["cmd_rmdir"] = { + "type": "bool", + "slider": False, + "label": "Enable: Removing directories", + "description": "Allows `rmdir` command execution", + "tooltip": "", + "value": True, + "min": None, + "max": None, + "multiplier": None, + "step": None, + } + self.options["cmd_copy_file"] = { + "type": "bool", + "slider": False, + "label": "Enable: Copying files", + "description": "Allows `copy` command execution", + "tooltip": "", + "value": True, + "min": None, + "max": None, + "multiplier": None, + "step": None, + } + self.options["cmd_copy_dir"] = { + "type": "bool", + "slider": False, + "label": "Enable: Copying directories (recursive)", + "description": "Allows `copy_dir` command execution", + "tooltip": "", + "value": True, + "min": None, + "max": None, + "multiplier": None, + "step": None, + } + self.options["cmd_move"] = { + "type": "bool", + "slider": False, + "label": "Enable: Move files and directories (rename)", + "description": "Allows `move` command execution", + "tooltip": "", + "value": True, + "min": None, + "max": None, + "multiplier": None, + "step": None, + } self.window = None self.order = 100 - self.allowed_cmds = ["save_file", "read_file", "append_file", "delete_file", "list_files", "list_dirs", "mkdir"] + self.allowed_cmds = [ + "save_file", + "read_file", + "append_file", + "delete_file", + "list_files", + "list_dirs", + "mkdir", + "download_file", + "rmdir", + "copy_file", + "copy_dir", + "move", + ] def setup(self): """ @@ -204,6 +279,16 @@ def cmd_syntax(self, syntax): syntax += '\n"list_dirs": list directories in directory, params: "path"' if self.is_cmd_allowed("mkdir"): syntax += '\n"mkdir": create directory, params: "path"' + if self.is_cmd_allowed("download_file"): + syntax += '\n"download_file": download file, params: "src", "dst"' + if self.is_cmd_allowed("rmdir"): + syntax += '\n"rmdir": remove directory, params: "path"' + if self.is_cmd_allowed("copy_file"): + syntax += '\n"copy_file": copy file, params: "src", "dst"' + if self.is_cmd_allowed("copy_dir"): + syntax += '\n"copy_dir": recursive copy directory, params: "src", "dst"' + if self.is_cmd_allowed("move"): + syntax += '\n"move": move file or directory, params: "src", "dst"' return syntax def cmd(self, ctx, cmds): @@ -212,96 +297,226 @@ def cmd(self, ctx, cmds): try: if item["cmd"] in self.allowed_cmds and self.is_cmd_allowed(item["cmd"]): if item["cmd"] == "save_file": - msg = "Saving file: {}".format(item["params"]['filename']) - print(msg) - path = os.path.join(self.window.config.path, 'output', item["params"]['filename']) - data = item["params"]['data'] - with open(path, 'w', encoding="utf-8") as file: - file.write(data) - file.close() - ctx.results.append({"request": item, "result": "OK"}) + try: + msg = "Saving file: {}".format(item["params"]['filename']) + print(msg) + path = os.path.join(self.window.config.path, 'output', item["params"]['filename']) + data = item["params"]['data'] + with open(path, 'w', encoding="utf-8") as file: + file.write(data) + file.close() + ctx.results.append({"request": item, "result": "OK"}) + ctx.reply = True + print("File saved: {}".format(path)) + except Exception as e: + ctx.results.append({"request": item, "result": "Error {}".format(e)}) ctx.reply = True - print("File saved: {}".format(path)) + print("Error: {}".format(e)) elif item["cmd"] == "append_file" and self.is_cmd_allowed("append_file"): - msg = "Appending file: {}".format(item["params"]['filename']) - print(msg) - path = os.path.join(self.window.config.path, 'output', item["params"]['filename']) - data = item["params"]['data'] - with open(path, 'a', encoding="utf-8") as file: - file.write(data) - file.close() - ctx.results.append({"request": item, "result": "OK"}) + try: + msg = "Appending file: {}".format(item["params"]['filename']) + print(msg) + path = os.path.join(self.window.config.path, 'output', item["params"]['filename']) + data = item["params"]['data'] + with open(path, 'a', encoding="utf-8") as file: + file.write(data) + file.close() + ctx.results.append({"request": item, "result": "OK"}) + ctx.reply = True + print("File appended: {}".format(path)) + except Exception as e: + ctx.results.append({"request": item, "result": "Error {}".format(e)}) ctx.reply = True - print("File appended: {}".format(path)) + print("Error: {}".format(e)) elif item["cmd"] == "read_file" and self.is_cmd_allowed("read_file"): - msg = "Reading file: {}".format(item["params"]['filename']) - print(msg) - path = os.path.join(self.window.config.path, 'output', item["params"]['filename']) - if os.path.exists(path): - with open(path, 'r', encoding="utf-8") as file: - data = file.read() - ctx.results.append({"request": item, "result": data}) - ctx.reply = True # send result message - file.close() - print("File read: {}".format(path)) - else: - ctx.results.append({"request": item, "result": "File not found"}) + try: + msg = "Reading file: {}".format(item["params"]['filename']) + print(msg) + path = os.path.join(self.window.config.path, 'output', item["params"]['filename']) + if os.path.exists(path): + with open(path, 'r', encoding="utf-8") as file: + data = file.read() + ctx.results.append({"request": item, "result": data}) + ctx.reply = True # send result message + file.close() + print("File read: {}".format(path)) + else: + ctx.results.append({"request": item, "result": "File not found"}) + ctx.reply = True + print("File not found: {}".format(path)) + except Exception as e: + ctx.results.append({"request": item, "result": "Error {}".format(e)}) ctx.reply = True - print("File not found: {}".format(path)) + print("Error: {}".format(e)) elif item["cmd"] == "delete_file" and self.is_cmd_allowed("delete_file"): - msg = "Deleting file: {}".format(item["params"]['filename']) - print(msg) - path = os.path.join(self.window.config.path, 'output', item["params"]['filename']) - if os.path.exists(path): - os.remove(path) + try: + msg = "Deleting file: {}".format(item["params"]['filename']) + print(msg) + path = os.path.join(self.window.config.path, 'output', item["params"]['filename']) + if os.path.exists(path): + os.remove(path) + ctx.results.append({"request": item, "result": "OK"}) + ctx.reply = True + print("File deleted: {}".format(path)) + else: + ctx.results.append({"request": item, "result": "File not found"}) + ctx.reply = True + print("File not found: {}".format(path)) + except Exception as e: + ctx.results.append({"request": item, "result": "Error {}".format(e)}) + ctx.reply = True + print("Error: {}".format(e)) + elif item["cmd"] == "list_files" and self.is_cmd_allowed("list_files"): + try: + msg = "Listing files: {}".format(item["params"]['path']) + print(msg) + path = os.path.join(self.window.config.path, 'output', item["params"]['path']) + if os.path.exists(path): + files = os.listdir(path) + ctx.results.append({"request": item, "result": files}) + ctx.reply = True + print("Files listed: {}".format(path)) + print("Result: {}".format(files)) + else: + ctx.results.append({"request": item, "result": "Directory not found"}) + ctx.reply = True + print("Directory not found: {}".format(path)) + except Exception as e: + ctx.results.append({"request": item, "result": "Error {}".format(e)}) + ctx.reply = True + print("Error: {}".format(e)) + elif item["cmd"] == "list_dirs" and self.is_cmd_allowed("list_dirs"): + try: + msg = "Listing directories: {}".format(item["params"]['path']) + print(msg) + path = os.path.join(self.window.config.path, 'output', item["params"]['path']) + if os.path.exists(path): + dirs = os.listdir(path) + ctx.results.append({"request": item, "result": dirs}) + ctx.reply = True + print("Directories listed: {}".format(path)) + print("Result: {}".format(dirs)) + else: + ctx.results.append({"request": item, "result": "Directory not found"}) + ctx.reply = True + print("Directory not found: {}".format(path)) + except Exception as e: + ctx.results.append({"request": item, "result": "Error {}".format(e)}) + ctx.reply = True + print("Error: {}".format(e)) + elif item["cmd"] == "mkdir" and self.is_cmd_allowed("mkdir"): + try: + msg = "Creating directory: {}".format(item["params"]['path']) + print(msg) + path = os.path.join(self.window.config.path, 'output', item["params"]['path']) + if not os.path.exists(path): + os.makedirs(path) + ctx.results.append({"request": item, "result": "OK"}) + ctx.reply = True + print("Directory created: {}".format(path)) + else: + ctx.results.append({"request": item, "result": "Directory already exists"}) + ctx.reply = True + print("Directory already exists: {}".format(path)) + except Exception as e: + ctx.results.append({"request": item, "result": "Error {}".format(e)}) + ctx.reply = True + print("Error: {}".format(e)) + elif item["cmd"] == "rmdir" and self.is_cmd_allowed("rmdir"): + try: + msg = "Deleting directory: {}".format(item["params"]['path']) + print(msg) + path = os.path.join(self.window.config.path, 'output', item["params"]['path']) + if os.path.exists(path): + shutil.rmtree(path) + ctx.results.append({"request": item, "result": "OK"}) + ctx.reply = True + print("Directory deleted: {}".format(path)) + else: + ctx.results.append({"request": item, "result": "Directory not found"}) + ctx.reply = True + print("Directory not found: {}".format(path)) + except Exception as e: + ctx.results.append({"request": item, "result": "Error {}".format(e)}) + ctx.reply = True + print("Error: {}".format(e)) + elif item["cmd"] == "download_file" and self.is_cmd_allowed("download_file"): + try: + dst = os.path.join(self.window.config.path, 'output', item["params"]['dst']) + msg = "Downloading file: {} into {}".format(item["params"]['src'], dst) + print(msg) + + # Check if src is URL + if item["params"]['src'].startswith("http"): + src = item["params"]['src'] + # Download file from URL + req = Request( + url=src, + headers={'User-Agent': 'Mozilla/5.0'} + ) + context = ssl.create_default_context() + context.check_hostname = False + context.verify_mode = ssl.CERT_NONE + with urlopen(req, context=context, timeout=4) as response, open(dst, 'wb') as out_file: + shutil.copyfileobj(response, out_file) + else: + # Handle local file paths + src = os.path.join(self.window.config.path, 'output', item["params"]['src']) + + # Copy local file + with open(src, 'rb') as in_file, open(dst, 'wb') as out_file: + shutil.copyfileobj(in_file, out_file) + + # handle result ctx.results.append({"request": item, "result": "OK"}) ctx.reply = True - print("File deleted: {}".format(path)) - else: - ctx.results.append({"request": item, "result": "File not found"}) + print("File downloaded: {} into {}".format(src, dst)) + except Exception as e: + ctx.results.append({"request": item, "result": "Error {}".format(e)}) ctx.reply = True - print("File not found: {}".format(path)) - elif item["cmd"] == "list_files" and self.is_cmd_allowed("list_files"): - msg = "Listing files: {}".format(item["params"]['path']) - print(msg) - path = os.path.join(self.window.config.path, 'output', item["params"]['path']) - if os.path.exists(path): - files = os.listdir(path) - ctx.results.append({"request": item, "result": files}) + print("Error: {}".format(e)) + elif item["cmd"] == "copy_file" and self.is_cmd_allowed("copy_file"): + try: + msg = "Copying file: {} into {}".format(item["params"]['src'], item["params"]['dst']) + print(msg) + dst = os.path.join(self.window.config.path, 'output', item["params"]['dst']) + src = os.path.join(self.window.config.path, 'output', item["params"]['src']) + shutil.copyfile(src, dst) + ctx.results.append({"request": item, "result": "OK"}) ctx.reply = True - print("Files listed: {}".format(path)) - print("Result: {}".format(files)) - else: - ctx.results.append({"request": item, "result": "Directory not found"}) + print("File copied: {} into {}".format(src, dst)) + except Exception as e: + ctx.results.append({"request": item, "result": "Error {}".format(e)}) ctx.reply = True - print("Directory not found: {}".format(path)) - elif item["cmd"] == "list_dirs" and self.is_cmd_allowed("list_dirs"): - msg = "Listing directories: {}".format(item["params"]['path']) - print(msg) - path = os.path.join(self.window.config.path, 'output', item["params"]['path']) - if os.path.exists(path): - dirs = os.listdir(path) - ctx.results.append({"request": item, "result": dirs}) + print("Error: {}".format(e)) + elif item["cmd"] == "copy_dir" and self.is_cmd_allowed("copy_dir"): + try: + msg = "Copying directory: {} into {}".format(item["params"]['src'], item["params"]['dst']) + print(msg) + dst = os.path.join(self.window.config.path, 'output', item["params"]['dst']) + src = os.path.join(self.window.config.path, 'output', item["params"]['src']) + shutil.copytree(src, dst) + ctx.results.append({"request": item, "result": "OK"}) ctx.reply = True - print("Directories listed: {}".format(path)) - print("Result: {}".format(dirs)) - else: - ctx.results.append({"request": item, "result": "Directory not found"}) + print("Directory copied: {} into {}".format(src, dst)) + except Exception as e: + ctx.results.append({"request": item, "result": "Error {}".format(e)}) ctx.reply = True - print("Directory not found: {}".format(path)) - elif item["cmd"] == "mkdir" and self.is_cmd_allowed("mkdir"): - msg = "Creating directory: {}".format(item["params"]['path']) - print(msg) - path = os.path.join(self.window.config.path, 'output', item["params"]['path']) - if not os.path.exists(path): - os.makedirs(path) + print("Error: {}".format(e)) + elif item["cmd"] == "move" and self.is_cmd_allowed("move"): + try: + msg = "Moving: {} into {}".format(item["params"]['src'], item["params"]['dst']) + print(msg) + dst = os.path.join(self.window.config.path, 'output', item["params"]['dst']) + src = os.path.join(self.window.config.path, 'output', item["params"]['src']) + shutil.move(src, dst) ctx.results.append({"request": item, "result": "OK"}) ctx.reply = True - print("Directory created: {}".format(path)) - else: - ctx.results.append({"request": item, "result": "Directory already exists"}) + print("Moved: {} into {}".format(src, dst)) + except Exception as e: + ctx.results.append({"request": item, "result": "Error {}".format(e)}) ctx.reply = True - print("Directory already exists: {}".format(path)) + print("Error: {}".format(e)) except Exception as e: ctx.results.append({"request": item, "result": "Error {}".format(e)}) ctx.reply = True diff --git a/src/pygpt_net/core/ui/widget/settings.py b/src/pygpt_net/core/ui/widget/settings.py index 2d40de8b0..35a49d982 100644 --- a/src/pygpt_net/core/ui/widget/settings.py +++ b/src/pygpt_net/core/ui/widget/settings.py @@ -351,8 +351,7 @@ def saveData(self): """ Save data """ - print("Dane zaktualizowane w modelu:") - print(self.items) + pass def updateData(self, data): """ diff --git a/version.rc b/version.rc index ce9ab23ed..7fd1d000a 100755 --- a/version.rc +++ b/version.rc @@ -1,7 +1,7 @@ VSVersionInfo( ffi=FixedFileInfo( - filevers=(2, 0, 8, 0), - prodvers=(2, 0, 8, 0), + filevers=(2, 0, 9, 0), + prodvers=(2, 0, 9, 0), mask=0x3f, flags=0x0, OS=0x4, @@ -15,13 +15,13 @@ StringFileInfo( StringTable( u'040904B0', [StringStruct(u'CompanyName', u'pygpt.net'), - StringStruct(u'FileDescription', u'AI Assistant powered by GPT-4, GPT-3 and DALL-E 3, assistant, chatbot, text completion, image generation and analyze'), - StringStruct(u'FileVersion', u'2.0.8'), + StringStruct(u'FileDescription', u'Desktop AI Assistant powered by GPT-4, GPT-3 and DALL-E 3: assistant, chatbot, text completion, image generation and analyze and more'), + StringStruct(u'FileVersion', u'2.0.9'), StringStruct(u'InternalName', u'Py-GPT'), StringStruct(u'LegalCopyright', u'(c) 2023 pygpt.net, Marcin Szczygliński'), StringStruct(u'OriginalFilename', u'Py-GPT.exe'), StringStruct(u'ProductName', u'pygpt.net'), - StringStruct(u'ProductVersion', u'2.0.8')]) + StringStruct(u'ProductVersion', u'2.0.9')]) ]), VarFileInfo([VarStruct(u'Translation', [1033, 1200])]) ]