動態命令執行,解析和存儲。
DynCommands允許您動態導入並運行Python功能。對於不重新啟動的情況下,可將命令添加到IRC聊天機器人或CLI應用程序中。
解析字符串時,它將命令名稱與參數分開,並使用這些參數執行存儲的函數。每次調用解析器時,您都可以傳遞自己的自定義kwargs,命令將可以訪問。
在允許運行之前,所有命令模塊均通過限制性PPYTHON進行編譯。您可以通過設置CommandParser._unrestricted to True關閉限制執行,儘管在運行不信任的代碼時會高度灰心。
from pathlib import Path
from dyncommands import CommandParser , CommandContext , CommandSource
output : str = ''
def callback ( text , * args ):
global output
output = text
path = Path ( 'path/to/directory' ) # Must be a directory with a `commands.json` file in it
parser = CommandParser ( path ) # Create the parser, which initializes using data located in the path directory
source = CommandSource ( callback ) # Create a source, which is used to talk back to the caller
input_ = 'command-that-returns-wow arg1 arg2' # this command would call zzz__command-that-returns-wow.py with arg1 and arg2
parser . parse ( CommandContext ( input_ , source )) # Parse the new context and run the command and callback (If no errors occur)
assert output == 'wow'命令的元數據存儲在commands.json目錄CommandParser.commands_path命令中。這是將解析器的所有數據加載和存儲的地方。
所有commands.json文件通過JSON Schemas通過JSonschema Python軟件包驗證
| 鑰匙 | 類型 | 描述 | 預設 | 必需的 |
|---|---|---|---|---|
commandPrefix | 細繩 | 字符串必須從此前綴開始,否則將被忽略。空字符串接受全部。 | N/A。 | 是的 |
commands | 數組[命令] | 包含存儲命令模塊的元數據。 | N/A。 | 是的 |
| 鑰匙 | 類型 | 描述 | 預設 | 必需的 |
|---|---|---|---|---|
name | 細繩 | 獨特地將命令標識為命令範圍。 | N/A。 | 是的 |
usage | 細繩 | 用法信息(如何使用ARGS)。 | “” | 不 |
description | 細繩 | 命令描述。 | “” | 不 |
permission | 整數 | CommandSource需要運行命令的權限級別。 | 0 | 不 |
function | 布爾,無效 | 是否有一個相關的Python模塊要加載。 | 無效的 | 不 |
children | 數組[命令] | 子命令;這些由父母的功能處理。 (無關的模塊本身)。 | [] | 不 |
overridable | 布爾 | CommandParser是否可以覆蓋該對象內部的任何數據(必須手動啟用)。 | 真的 | 不 |
disabled | 布爾 | 如果true仍然加載命令,但是在嘗試執行時會提出殘疾人。 | 錯誤的 | 不 |
注意:命令模塊沒有加載,除非將它們列在commands.json中function
commands.json內容: {
"commandPrefix" : " ! " ,
"commands" : [
{
"name" : " test " ,
"usage" : " test [*args:any] " ,
"description" : " Test command. " ,
"permission" : 500 ,
"function" : true
},
{
"name" : " test2 " ,
"function" : false
}
]
}動態加載的命令用“ zzz__”前綴表示,用文件名表示。在命令模塊中,有一個函數定義為command 。此函數將映射到Command的函數屬性並存儲在內存中以進行執行。該功能可以訪問被解析的任何ARG以及Kwargs:
“ self ”( Command ),該(命令)容納正在執行的命令的元數據。
“ CommandParser ”( CommandParser ),該命令列表和命令數據列表。
“上下文”( CommandContext ),它提供CommandSource和發送的原始文本。
CommandParser.parse(context: CommandContext, **kwargs) 。由於命令無法導入自己的模塊,因此有些包含在Globals( math , random和string )中。全局範圍中包含的其他屬性是: getitem ( operator.getItem )和ImproperUsageError ( dyncommands.exceptions.improperusageerror )。
def command ( * args , ** kwargs ):
self , context = kwargs . pop ( 'self' ), kwargs . pop ( 'context' )
source = context . source
if len ( args ) == 2 :
amount , sides = abs ( int ( getitem ( args , 0 ))), abs ( int ( getitem ( args , 1 )))
if amount > 0 and sides > 0 :
dice_rolls = [ f" { ( str ( i + 1 ) + ':' ) if amount > 1 else '' } { str ( random . randint ( 1 , sides )) } / { sides } " for i in range ( amount )]
source . send_feedback ( f"/me U0001f3b2 { source . display_name } rolled { 'a die' if amount == 1 else str ( amount ) + ' dice' } with { sides } side { '' if sides == 1 else 's' } : { ', ' . join ( dice_rolls ) } U0001f3b2 " )
else :
raise ImproperUsageError ( self , context )
else :
raise ImproperUsageError ( self , context )您可以隨時調用CommandParser.reload()從磁盤存儲中重新加載所有命令模塊和元數據。
../
│
├───[commands_path]/
│ ├─── commands.json
│ ├─── zzz__[command1].py
│ ├─── zzz__[command2].py
│ └─── zzz__[command3].py
│
要添加命令,您可以手動將數據輸入commands.json CommandParser.add_command(text: str, link: bool = False, **kwargs)使用此方法的最簡單方法是將命令模塊讀取為文本並將其傳遞給第一個參數。您還可以在線存儲命令模塊以允許遠程安裝,因為將鏈接參數設置為true將以鏈接讀取文本,並將從該鏈接獲取原始文本數據。例如:要點和粘貼。
注意:添加命令時,必須填充“名稱”的元數據。這可以以評論的形式完成。
刪除已經添加的命令相對容易。只需調用CommandParser.remove_command(name: str)帶有要刪除的命令的名稱,它將從磁盤中刪除元數據和命令模塊。
如果您不想在刪除時刪除命令,則更好的選擇是用CommandParser.set_disabled(name: str, value: bool)禁用它。
# Name: points
# Usage: points [get (username:string) | set (username:string amount:integer)]
# Description: Get your current points
# Permission: 0
# Children: [{'name': 'get', 'usage': 'get (username:string)', 'permission':0}, {'name': 'set', 'usage': 'set (username:string amount:integer)', 'permission':500}]
def command ( * args , ** kwargs ):
... parser = CommandParser ( './' )
with open ( 'some_metadata.json' ) as _file :
get_ = { 'name' : 'get' , 'usage' : 'get (username:string)' , 'permission' : 0 }
set_ = { 'name' : 'set' , 'usage' : 'set (username:string amount:integer)' , 'permission' : 500 }
children = [ get_ , set_ ]
parser . add_command ( _file . read (), name = 'my-command' , description = 'Command with child commands.' , children = children ) parser = CommandParser ( './' )
with open ( 'some_metadata.json' ) as _file :
metadata = json . load ( _file )
parser . add_command ( 'https://gist.github.com/random/892hdh2fh389x0wcmksio7m' , link = True , ** metadata ) DynCommand CommandParser本地支持權限級別的處理,因此您不必在每個命令函數中實現類似的系統。
每個命令都有元數據值permission (特殊值-1除外)是CommandSource所需的最低權限級別。 -1表示“無限”的要求,在該許可系統處於活動狀態時,沒有CommandSource可以執行它。
要禁用權限系統,請將CommandParser的s _ignore_permission屬性設置為true。注意:由於此屬性以“ _”開頭,因此嘗試從命令的功能內部更改它將導致彙編失敗和例外。