前言 aardio中有些經常使用的庫,換個項目總需要複製一下,還不便於修改。雖然可以直接把它放到aardio\lib目錄下,也是不便於共用給其他人使用。 最近偶然翻到編輯器里的工具->開發環境->擴展庫發佈工具,就想著可以像官方一樣,發佈自己的擴展庫,也便於分享給大家使用,最好能像官方擴展庫一樣線上 ...
前言
aardio中有些經常使用的庫,換個項目總需要複製一下,還不便於修改。雖然可以直接把它放到aardio\lib
目錄下,也是不便於共用給其他人使用。
最近偶然翻到編輯器里的工具
->開發環境
->擴展庫發佈工具
,就想著可以像官方一樣,發佈自己的擴展庫,也便於分享給大家使用,最好能像官方擴展庫一樣線上安裝。
閱讀官方代碼
翻了一下代碼,其實官方擴展庫的邏輯也很簡單,先請求一遍所有擴展庫列表,這是個json文件。
裡面包含擴展庫的基本信息和下載的url,下載的格式是.tar.lzma
,而上面的擴展庫發佈工具就是將庫打包成這個格式。
當你要安裝某個庫時,就會把它下載並解壓到aardio\lib
文件夾下。
寫好的成品
下麵是我弄的擴展庫,目前庫只有幾個,基本都是我最近才寫的,有興趣的可以去github下載測試下bug。
歡迎大家共用一些常用庫,減少造輪子的時間。
開源地址
搭建的代碼放到github了,你可以簡單的修改代碼裡面的倉庫地址來做一個自己的擴展倉庫
github:https://github.com/kanadeblisst00/aardio-extlibs
github的訪問國內偶爾會抽風,所以我擴展庫里的下載地址放的是國內伺服器搭建的鏡像倉庫(它會每10分鐘同步上面github的數據)
國內加速倉庫: http://git.pygrower.cn/kanadeblisst/aardio-extlibs
使用方法
先下載extlibs.aardio
這個文件到本地(只需要這個文件,其他都是打包的代碼,這個是下載的代碼)
把它重命名為5.extlibs.aardio
,移動到aardio\tools
文件夾下,該目錄下還有個1.ext.aardio
文件,這是官方擴展庫。
接著重新打開aardio的編輯器,就可以在工具里看到有個非官方擴展庫
。使用方法和上面的擴展庫是一樣的,運行它選擇需要安裝的庫,它就會下載好放到aardio\lib
目錄下
搭建教程
上面的倉庫里的代碼就是搭建的全部代碼。這裡我簡單的說一下這些代碼流程
目錄結構
- dist: 打包後的文件,用於在
extlibs.aardio
里遠程下載安裝 - lib: 庫代碼
- res: 庫的使用案例
- main.aardio: 將lib下的庫打包壓縮到dist里
搭建步驟
將你需要打包的庫放在lib目錄下,然後打開這個項目並運行。它會將lib下的所有庫打包成tar文件放在dist\package
目錄下。
還會將res目錄存放的案例打包成zip放到dist\samples
下,同時生成庫的json信息。而dist\exlibs.json
是所有庫的彙總信息。
格式如下:
{
"goquery":{
"author":"kanadeblisst",
"description":"goquery封裝庫,用於解析HTML",
"url":"http://git.pygrower.cn/kanadeblisst/aardio-extlibs/raw/branch/master/dist/package/goquery.tar.lzma",
"version":"1.0.0.1",
"weight":1
}
}
後面只需把項目代碼(extlibs.aardio
和main.aardio
)里的git地址換成你自己的git地址
thread.set("GithubRepo", "http://git.pygrower.cn/kanadeblisst/aardio-extlibs");
具體流程
運行了項目之後就會在dist目錄下生成需要的文件,而這些文件都可以通過鏈接直接訪問到。
比如exlibs.json
的鏈接就是倉庫地址+ /raw/branch/master/dist/exlibs.json
,這樣就能下載到所有的庫信息,然後把它顯示到界面。
下載的函數只需要在ide.requestLibInfo
這個庫函數基礎上修改下url,代碼如下
var requestLibInfo = function(libName){
return ..thread.invokeAndWait(
function(libName){
import web.rest.jsonLiteClient;
var repoUrl = thread.get("GithubRepo");
var url = repoUrl + "/raw/branch/master/dist/exlibs.json";
var http = web.rest.jsonLiteClient(null,"");
var libApi = http.api(url)
var listLib = libApi.get();
http.close();
var lib;
if(libName){
lib = listLib[libName];
lib["libName"] = libName;
}else{
lib = listLib;
}
return lib;
},libName
)
};
requestLibInfo
官方使用的ide.requestLibInfo
來下載庫信息。但url是在函數里寫死的,我並不想修改ide這個庫的代碼,又想讓這個函數去我指定的鏈接下載庫信息,怎麼操作最方便?
最先想到的肯定是將var libs = ide.requestLibInfo();
改成var libs = requestLibInfo();
,我不用它就行了。
但有個問題ide.installLib
方法也被使用了,而且還調用了ide.requestLibInfo
,難道又要重寫installLib
?
偷懶的修改方式
當然不用,修改的話很簡單,只需要多加一行代碼:
import ide;
ide.requestLibInfo = requestLibInfo;
var libs = ide.requestLibInfo();
新增了ide.requestLibInfo = requestLibInfo;
這行代碼後,在ide.installLib
里調用的ide.requestLibInfo
也會被替換成我的函數。
這樣就只多了一行代碼,不用去重寫多個函數。如果在多線程使用的話,同樣需要新增這行代碼。
hook
上面這個思路其實很常見,專業名詞的話是hook。比如我之前寫的Python調用ocr,有人提了個需求:https://github.com/kanadeblisst00/wechat_ocr/issues/6
這個需求很小眾,根本不用去修改庫代碼來實現,只需要hook一下print就能做到:
import builtins
def my_print(*args, **kwargs):
pass
builtins.print = my_print
如果只想過濾某個模塊的print,可以通過inspect模塊獲取上上層調用的函數和所在模塊,根據函數名或模塊名就能過濾掉指定模塊的print列印
import builtins
def caller_info():
# 獲取當前幀的上一幀,即調用者的幀
caller_frame = inspect.currentframe().f_back.f_back
# 獲取調用者所在的模塊和函數
caller_module = inspect.getmodule(caller_frame)
caller_name = caller_frame.f_code.co_name
# 如果能獲取到調用者模塊,則提取模塊名;否則為None
module_name = caller_module.__name__ if caller_module else None
return module_name, caller_name
old_print = builtins.print
def my_print(*args, **kwargs):
module_name, caller_name = caller_info()
if "ocr" not in module_name:
old_print(*args, **kwargs)
builtins.print = my_print
本文由博客一文多發平臺 OpenWrite 發佈!