تنفيذ الأوامر الديناميكية ، التحليل ، والتخزين.
يتيح لك DynCommands استيراد وتشغيل وظائف Python ديناميكيًا. مفيد لإضافة الأوامر إلى chatbots IRC أو تطبيقات CLI دون إعادة التشغيل.
عند تحليل السلسلة ، يفصل اسم الأمر عن الوسائط ، ويقوم بتنفيذ الوظيفة المخزنة مع تلك الوسائط. في كل مرة يتم فيها استدعاء المحلل ، يمكنك تمريرها في Kwargs المخصصة التي سيتمكن الأمر من الوصول إليه.
يتم تجميع جميع وحدات الأوامر من خلال RidedPyThon قبل السماح لها بالركض. يمكنك إيقاف تشغيل التنفيذ المقيد عن طريق تعيين CommandParser._unrestricted إلى 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' يتم تخزين بيانات CommandParser.commands_path للأوامر في ملف commands.json . هذا هو المكان الذي يتم فيه تحميل وتخزين جميع بيانات المحلل.
يتم التحقق من صحة ملفات all commands.json باستخدام مخططات JSON من خلال حزمة Jsonschema Python
| مفتاح | يكتب | وصف | تقصير | مطلوب |
|---|---|---|---|---|
commandPrefix | خيط | يجب أن تبدأ السلاسل مع هذه البادئة ، وإلا يتم تجاهلها. السلسلة الفارغة تقبل كل شيء. | ن/أ | نعم |
commands | صفيف [ أمر ] | يحتوي على بيانات تعريف لوحدات الأوامر المخزنة. | ن/أ | نعم |
| مفتاح | يكتب | وصف | تقصير | مطلوب |
|---|---|---|---|---|
name | خيط | يحدد الأمر بشكل فريد الأمر إلى CommandParser. | ن/أ | نعم |
usage | خيط | معلومات الاستخدام (كيفية استخدام args). | "" " | لا |
description | خيط | وصف الأوامر. | "" " | لا |
permission | عدد صحيح | مستوى الإذن الذي يتطلب الأمر تشغيل الأوامر لتشغيل الأمر. | 0 | لا |
function | منطقية ، فارغة | ما إذا كان هناك وحدة بيثون مرتبطة للتحميل. | باطل | لا |
children | صفيف [ أمر ] | الأوامر الفرعية ؛ يتم التعامل مع هذه وظيفة الوالد. (لا توجد وحدات مرتبطة لأنفسهم). | [] | لا |
overridable | منطقية | ما إذا كان يمكن لـ CommandParser تجاوز أي بيانات داخل هذا الكائن (يجب تمكينه يدويًا). | حقيقي | لا |
disabled | منطقية | إذا كان True لا يزال تحميل الأمر ، ولكن قم برفع عملية تعطيل عند محاولة التنفيذ. | خطأ شنيع | لا |
ملاحظة: لا يتم تحميل وحدات الأوامر إلا إذا تم إدراجها في commands.json مع تعيين مفتاح function على TRUE .
commands.json contents: {
"commandPrefix" : " ! " ,
"commands" : [
{
"name" : " test " ,
"usage" : " test [*args:any] " ,
"description" : " Test command. " ,
"permission" : 500 ,
"function" : true
},
{
"name" : " test2 " ,
"function" : false
}
]
} يتم الإشارة إلى الأوامر المحملة ديناميكيًا بواسطة اسم الملف ببادئة "ZZZ__". داخل وحدة الأوامر ، هناك وظيفة محددة command . سيتم تعيين هذه الوظيفة إلى سمة وظيفة Command وتخزينها في الذاكرة للتنفيذ. تتمتع الوظيفة بإمكانية الوصول إلى أي args تم تحليلها ، وكذلك Kwargs:
" Self " ( Command ) ، الذي يضم البيانات الوصفية للقيادة التي يتم تنفيذها.
" المحللون " ( 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 سوف تقرأ النص كوصلة ، وسيحصل على بيانات النص الخام من هذا الرابط. على سبيل المثال: Gist و Pastebin.
ملاحظة: عند إضافة أمر ، يجب ملء البيانات الوصفية لـ "الاسم". يمكن القيام بذلك في شكل تعليقات.
من السهل نسبيًا إزالة أمر تمت إضافته بالفعل. ما عليك سوى استدعاء CommandParser.remove_command(name: str) باسم الأمر الذي تريد إزالته ، وسيحذف كل من Metadata ووحدة الأوامر من القرص.
إذا كنت لا ترغب في حذف الأمر عند الإزالة ، فإن البديل الأفضل هو تعطيله باستخدام 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 ) يدعم CommandParser Dyncommand NAWE معالجة مستوى الإذن ، لذلك لا يتعين عليك تنفيذ نظام مماثل في كل وظيفة أمر.
كل أمر لديه permission بيانات البيانات الوصفية ، (باستثناء القيمة الخاصة -1 ) هو الحد الأدنى لمستوى الإذن المطلوب من CommandSource . -1 يمثل متطلبات "لا حصر لها" ، حيث لن يتمكن أي CommandSource من تنفيذها أثناء نشط نظام الإذن.
لتعطيل نظام الإذن ، قم بتعيين سمة CommandParser من _ignore_permission إلى True. ملاحظة: نظرًا لأن هذه السمة تبدأ بـ "_" ، فإن محاولة تغييرها من وظيفة الأمر ستؤدي إلى تجميع فاشل واستثناء.