From f2e670b9a83a55597e3681618721553007b68bbc Mon Sep 17 00:00:00 2001 From: Evgeny Date: Thu, 19 Aug 2021 15:41:40 +0300 Subject: [PATCH] add apps module --- README.md | 16 +++++++++++++++- README_ru.md | 16 +++++++++++++++- gen_zip.sh | 2 +- lib/utils.lua | 11 +++++++++++ samples/app-buttons-sample.lua | 2 +- samples/apps-sample.lua | 28 ++++++++++++++++++++++++++++ samples/table-sample.lua | 9 +++++---- scripts.md5 | 1 + scripts.zip | Bin 0 -> 16744 bytes 9 files changed, 77 insertions(+), 8 deletions(-) create mode 100644 samples/apps-sample.lua create mode 100644 scripts.md5 create mode 100644 scripts.zip diff --git a/README.md b/README.md index 0c97759..e0f76db 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,6 @@ When you click on any menu item, the callback `on_context_menu_click(item_idx, m # System functions -* `system:open_app(package_name)` - opens the application by package name; * `system:open_browser(url)` - opens the specified URL in a browser or application that can handle this type of URL; * `system:exec(string)` - executes a shell command; * `system:su(string)` - executes a shell command as root; @@ -101,6 +100,20 @@ The result of executing a shell command is sent to the `on_shell_result(string)` If there is a `arguments_help` field in the widget's metadata, its value will be displayed when editing the widget's arguments. If there is a `arguments_default` field, it will be used to get the default arguments. +# Application management functions + +* `apps:get_list([sort_by])` - returns a table of package names of all installed applications, `sort_by` - sort option (see below); +* `apps:get_name(package)` - returns application name; +* `apps:get_color(package)` - returns the color of the application in #XXXXXXXX format; +* `apps:launch(package)` - launches the application. + +Sorting options: + +* `abc` - alphabetical (default); +* `launch_count` - by number of launches; +* `launch_time` - by launch time; +* `install_time` - by installation time. + # Network functions * `http:get(url, [id])` - executes an HTTP GET request, id - the request identifier string (see below); @@ -169,6 +182,7 @@ The standard Lua API is extended with the following features: * `string:split(delimeter)` - splits the string using the specified delimiter and returns a table; * `string:replace(regexp, string)` - replaces the text found by the regular expression with another text; +* `slice(table, start, end)` - returns the part of the table starting with the `start` index and ending with `end` index; * `get_index(table, value)` - returns the index of the table element; * `get_key(table, value)` - returns the key of the table element; * `round(x, n)` - rounds the number; diff --git a/README_ru.md b/README_ru.md index e7c2a9f..3ff6c3f 100644 --- a/README_ru.md +++ b/README_ru.md @@ -77,7 +77,6 @@ ui:prepare_context_menu({ # Системные функции -* `system:open_app(package_name)` - открывает приложение, имя пакета которого указано в аргументе; * `system:open_browser(url)` - открывает указанный URL в браузере или в приложении, умеющем обрабатывать данный тип URL; * `system:exec(string)` - выполняет shell-команду; * `system:su(string)` - выполняет shell-команду от имени root; @@ -101,6 +100,20 @@ ui:prepare_context_menu({ Если в метаданных виджета есть поле `arguments_help`, его значение будет выведено при редактировании аргументов виджета. Если есть поле `arguments_default` - оно будет использовано для получения дефолтовых аргументов. +# Функции управления приложениями + +* `apps:get_list([sort_by])` - возвращает таблицу пакетов всех установленных приложений, `sort_by` - вариант сортировки (см. ниже); +* `apps:get_name(package)` - возвращает имя приложения; +* `apps:get_color(package)` - возвращает цвет приложения в формате #XXXXXX; +* `apps:launch(package)` - запускает приложение. + +Варианты сортировки: + +* `abc` - по алфавиту (по умолчанию); +* `launch_count` - по количеству запусков; +* `launch_time` - по времени запуска; +* `install_time` - по времени установки. + # Сетевые функции * `http:get(url, [id])` - выполняет запрос HTTP GET, id - строка-идентификатор запрос (см. ниже); @@ -169,6 +182,7 @@ AIO Launcher включает в себя интерпретатор LuaJ 3.0.1 * `string:split(delimeter)` - разделяет строку с помощью указанного разделителя и возвращает таблицу; * `string:replace(regexp, string)` - заменяет текст, найденный регулярным выражением, на другой текст; +* `slice(table, start, end)` - возвращает часть таблицы, начиная с индекса `start` и заканчивая `end`; * `get_index(table, value)` - возвращает индекс элемента таблицы; * `get_key(table, value)` - возвращает ключ элемента таблицы; * `round(x, n)` - округляет число; diff --git a/gen_zip.sh b/gen_zip.sh index a8aec92..6dd8c05 100755 --- a/gen_zip.sh +++ b/gen_zip.sh @@ -1,5 +1,5 @@ #!/bin/sh -rm -rf scripts.zip +rm -rf scripts.zip scripts.md5 zip -r scripts.zip -j main/*.lua community/*.lua ru/*.lua md5sum scripts.zip | cut -d " " -f 1 > scripts.md5 diff --git a/lib/utils.lua b/lib/utils.lua index fdafb21..16c4257 100644 --- a/lib/utils.lua +++ b/lib/utils.lua @@ -18,6 +18,17 @@ function string:replace(from, to) return self:gsub(from, to) end +function slice(tbl, s, e) + local pos, new = 1, {} + + for i = s, e do + new[pos] = tbl[i] + pos = pos + 1 + end + + return new +end + function get_index(tab, val) for index, value in ipairs(tab) do if value == val then diff --git a/samples/app-buttons-sample.lua b/samples/app-buttons-sample.lua index 3aeb328..9fc350b 100644 --- a/samples/app-buttons-sample.lua +++ b/samples/app-buttons-sample.lua @@ -9,5 +9,5 @@ function on_resume() end function on_click(idx) - system:open_app(apps_pkgs[idx]) + apps:launch(apps_pkgs[idx]) end diff --git a/samples/apps-sample.lua b/samples/apps-sample.lua new file mode 100644 index 0000000..629afc3 --- /dev/null +++ b/samples/apps-sample.lua @@ -0,0 +1,28 @@ +-- global vars +all_apps = {} + +function on_resume() + all_apps = apps:get_list("launch_count") + + if (next(all_apps) == nil) then + ui:show_text("The list of apps is not ready yet") + return + end + + local apps_names = {} + for k,v in ipairs(all_apps) do + apps_names[k] = get_formatted_name(v) + end + + ui:show_table(slice(apps_names, 1, 9), 3) +end + +function on_click(idx) + apps:launch(all_apps[idx]) +end + +-- utils + +function get_formatted_name(pkg) + return ""..apps:get_name(pkg).."" +end diff --git a/samples/table-sample.lua b/samples/table-sample.lua index f4a92af..b02ef7f 100644 --- a/samples/table-sample.lua +++ b/samples/table-sample.lua @@ -1,11 +1,12 @@ function on_resume() local table = { - "1", "20", "30", - "40", "5", "66", - "07", "28", "9", + "12345678", "", "", + "1", "2", "3", + "4", "5", "6", + "7", "8", "9", } - ui:show_table(table, 3, true, "Nothing there") + ui:show_table(table, 3, true, false, "Nothing there") end function on_click(idx) diff --git a/scripts.md5 b/scripts.md5 new file mode 100644 index 0000000..34aec90 --- /dev/null +++ b/scripts.md5 @@ -0,0 +1 @@ +68a451374fa801b069e69ed75156c862 diff --git a/scripts.zip b/scripts.zip new file mode 100644 index 0000000000000000000000000000000000000000..49322124ef654c17899fe762c7d47c79ad830122 GIT binary patch literal 16744 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 R5NzOw2zd3easB-3{{U&&LZ1Kt literal 0 HcmV?d00001