--[[ @object-name: ui @object-desc: UI 操作 --]] local utils = require "oui.utils" local sys = require "oui.system" local cjson = require "cjson" local rpc = require "oui.rpc" local fs = require "oui.fs" local db = require "oui.db" local ubus = require "ubus" local uci = require "uci" local M = {} local RPC_OUI_MENU_FILES_PATH = "/usr/share/oui/menu.d" local RPC_OUI_LOCALES_PATH = "/www/i18n" local function set_repo_url(lang) if lang == "zh-cn" then os.execute("sed -i 's/fw.gl-inet.com/fw.gl-inet.cn/' /etc/opkg/distfeeds.conf"); else os.execute("sed -i 's/fw.gl-inet.cn/fw.gl-inet.com/' /etc/opkg/distfeeds.conf"); end end --[[ @method-type: call @method-name: get_lang @method-desc: 获取语言 @method-noauth @out string lang 语言(auto 表示自动) @out array list 支持的语言列表 @out string list.value 语言代码 @out string list.lable 语言说明 @in-example: {"jsonrpc":"2.0","id":1,"method":"call","params":["","ui","get_lang"]} @out-example: {"jsonrpc": "2.0", "id": 1, "result": { "lang": "auto", "list":[{"value": "en", "lable":"English"}, {"value": "zh-cn", "lable":"简体中文"}, {"value": "zh-tw", "lable":"繁体中文"},{"value": "ja", "lable":"日本語"}] }} --]] function M.get_lang() local c = uci.cursor() return { lang = c:get("oui-httpd", "main", "lang") } end --[[ @method-type: call @method-name: set_lang @method-desc: 获取语言 @in string lang 要设置的语言(auto 表示自动) @out string lang 当前语言 @in-example: {"jsonrpc":"2.0","id":1,"method":"call","params":["","ui","set_lang",{"lang":"auto"}]} @out-example: {"jsonrpc": "2.0", "id": 1, "result": { "lang": "auto" }} --]] function M.set_lang(params) local c = uci.cursor() if type(params.lang) ~= "string" then return rpc.ERROR_CODE_INVALID_PARAMS end c:set("oui-httpd", "main", "lang", params.lang) c:commit("oui-httpd") set_repo_url(params.lang) return { lang = c:get("oui-httpd", "main", "lang") } end --[[ @method-type: call @method-name: get_menu_list @method-desc: 获取菜单列表 @out array menus 当前菜单列表 @in-example: {"jsonrpc":"2.0","id":1,"method":"call","params":["","ui","get_menu_list"]} @out-example: {"jsonrpc":"2.0","id":1,"result":{"menus":[{"title":"Network","index":30,"path":"/network","children":[{"title":"DHCP/DNS","path":"/network/dhcp","index":40,"view":"oui-app-dhcp"}]},{"title":"Test","index":31,"path":"/test","view":"oui-app-test"}]}} --]] function M.get_menu_list() local menus = {} for name in fs.dir(RPC_OUI_MENU_FILES_PATH) do if name:match("%.json$") then local file = RPC_OUI_MENU_FILES_PATH .. "/" .. name local menu = cjson.decode(utils.readfile(file)) menus[#menus + 1] = menu end end return {menus = menus} end --[[ @method-type: call @method-name: load_locales @method-desc: 加载翻译对象 @method-noauth @in string locale 语言代码 @out array locales 翻译对象列表(前端需要将该数组合并一个 JSON 对象) @in-example: {"jsonrpc":"2.0","id":1,"method":"call","params":["","ui","load_locales", {"locale": "en"}]} @out-example: {"jsonrpc": "2.0", "id": 1, "result": {"locales": [{"IPv4-Address": "IPv4-Address", "Services": "Services"}, {"Output": "Output", "Month Days": "Month Days"}]}} --]] function M.load_locales(params) local locales = {} if type(params.locale) ~= "string" then return rpc.ERROR_CODE_INVALID_PARAMS end local match = string.format("%%.%s.json$", params.locale):gsub("%-", "%%-") for name in fs.dir(RPC_OUI_LOCALES_PATH) do if name:match(match) then local file = RPC_OUI_LOCALES_PATH .. "/" .. name local data = utils.readfile(file) local locale = cjson.decode(data) locales[#locales + 1] = locale end end return { locales = locales } end --[[ @method-type: call @method-name: check_initialized @method-desc: 查询是否已初始化 @method-noauth @out bool initialized 是否已初始化 @out string model 设备型号 @out string hostname 设备主机名 @out string mac 设备标签上的MAC地址 @out string firmware_version 固件版本 @out number security_rule 安全法规选项,用于满足不同法规的不同安全需求(0:无安全法规需求;1:通用安全法规需求) @out string firmware_category 固件类型(目前有2个取值: "2c", "2b") @out object brand 2B 固件自定义信息 @out string brand.enterprise_name 企业名称 @out string brand.copyright 版权信息 @out string brand.official_website 企业官网链接 @in-example: {"jsonrpc":"2.0","id":1,"method":"call","params":["","ui","check_initialized"]} @out-example: {"jsonrpc": "2.0", "id": 1, "result": {"initialized": true, "model":"x750", "hostname":"GL-X750", "mac":"e4:95:6e:30:24:38", "firmware_version": "1.2", "security_rule": 1}} --]] function M.check_initialized() local c = uci.cursor() local model = c:get("board_special", "hardware", "model") or "" if model == "" then model = utils.readfile("/proc/gl-hw-info/model", "l") end local firmware_category = utils.readfile("/etc/firmware_type", "l") if not firmware_category or firmware_category == "" then firmware_category = "2c" end local brand if firmware_category == "2b" then brand = { enterprise_name = c:get("glconfig", "brand", "enterprise_name"), copyright = c:get("glconfig", "brand", "copyright"), official_website = c:get("glconfig", "brand", "official_website") } end return { initialized = c:get("oui-httpd", "main", "inited") == "1", hostname = c:get("system", "@system[0]", "hostname") or "", model = model, mac = string.upper(utils.readfile("/proc/gl-hw-info/device_mac", "l") or ""), firmware_version = fs.access("/etc/glversion") and utils.readfile("/etc/glversion", "l") or "", security_rule = tonumber(c:get("oui-httpd", "main", "security_rule")), firmware_category = firmware_category, brand = brand } end --[[ @method-type: call @method-name: init @method-desc: 初始化 @method-noauth @in string lang 语言 @in string username 用户名 @in string password 密码 @in string ?ssid 2.4G SSID @in string ?encryption_wifi 2.4G WiFi 加密方式 @in string ?password_wifi 2.4G WiFi 密码 @in string ?ssid_5g 5G SSID @in string ?encryption_wifi_5g 5G WiFi 加密方式 @in string ?password_wifi_5g 5G WiFi 密码 @in string ?location 路由器的摆放位置 @in bool redirect_https 是否重定向 HTTP 到 HTTPS @in number ?security_rule 安全法规选项,用于满足不同法规的不同安全需求(0:无安全法规需求;1:通用安全法规需求) @in-example: {"jsonrpc":"2.0","id":1,"method":"call","params":["","ui","init", {"lang":"auto","username":"admin","password":"123","ssid":"gl-x750","password_wifi":"goodlife","location":"bedroom","security_rule":1}]} @out-example: {"jsonrpc": "2.0", "id": 1, "result": {}} --]] function M.init(params) if M.check_initialized().initialized then return rpc.ERROR_CODE_ACCESS end local c = uci.cursor() local username, password = params.username, params.password local lang = params.lang local location = params.location local redirect_https = params.redirect_https local security_rule = params.security_rule if type(lang) ~= "string" or type(username) ~= "string" or type(password) ~= "string" then return rpc.ERROR_CODE_INVALID_PARAMS end local r, err = sys.password(username, "", password) if not r then return rpc.ERROR_CODE_ACCESS, err end db.add_user(username) c:set("oui-httpd", "main", "lang", lang) set_repo_url(lang) c:set("oui-httpd", "main", "inited", "1") if redirect_https ~= nil then c:set("oui-httpd", "main", "redirect_https", redirect_https and 1 or 0) end if security_rule then c:set("oui-httpd", "main", "security_rule", security_rule) end c:commit("oui-httpd") c:foreach("wireless", "wifi-iface", function(s) if s.network == "guest" then return end local band = c:get("wireless", s.device, "band") if band == "2g" then if params.ssid then c:set("wireless", s[".name"], "ssid", params.ssid) end if params.encryption_wifi then c:set("wireless", s[".name"], "encryption", params.encryption_wifi) end if params.password_wifi then c:set("wireless", s[".name"], "key", params.password_wifi) end else if params.ssid_5g then c:set("wireless", s[".name"], "ssid", params.ssid_5g) end if params.encryption_wifi_5g then c:set("wireless", s[".name"], "encryption", params.encryption_wifi_5g) end if params.password_wifi_5g then c:set("wireless", s[".name"], "key", params.password_wifi_5g) end end end) c:commit("wireless") if location then c:set("glconfig", "@system[0]", "location", location) c:commit("glconfig") end if fs.access("/usr/bin/remove_portal_firewall") then ngx.pipe.spawn({"/usr/bin/remove_portal_firewall"}) end fs.sync() ngx.timer.at(1, function() local conn = ubus.connect() conn:call("network", "reload", {}) conn:call("network.interface.wan", "down", {}) conn:call("network.interface.wan", "up", {}) conn:close() end) end return M