<commit_before>--[[
LuCI - Lua Configuration Interface
Copyright 2019 lisaac <https://github.com/lisaac/luci-app-dockerman>
]]--

require "luci.util"
local uci = luci.model.uci.cursor()
local docker = require "luci.model.docker"
local dk = docker.new()
local cmd_line = table.concat(arg, '/')
local create_body = {}

local images = dk.images:list().body
local networks = dk.networks:list().body
local containers = dk.containers:list({query = {all=true}}).body

local is_quot_complete = function(str)
  require "math"
  if not str then return true end
  local num = 0, w
  for w in str:gmatch("\"") do
    num = num + 1
  end
  if math.fmod(num, 2) ~= 0 then return false end
  num = 0
  for w in str:gmatch("\'") do
    num = num + 1
  end
  if math.fmod(num, 2) ~= 0 then return false end
  return true
end

local resolve_cli = function(cmd_line)
  local config = {advance = 1}
  local key_no_val = '|t|d|i|tty|rm|read_only|interactive|init|help|detach|privileged|P|publish_all|'
  local key_with_val = '|sysctl|add_host|a|attach|blkio_weight_device|cap_add|cap_drop|device|device_cgroup_rule|device_read_bps|device_read_iops|device_write_bps|device_write_iops|dns|dns_option|dns_search|e|env|env_file|expose|group_add|l|label|label_file|link|link_local_ip|log_driver|log_opt|network_alias|p|publish|security_opt|storage_opt|tmpfs|v|volume|volumes_from|blkio_weight|cgroup_parent|cidfile|cpu_period|cpu_quota|cpu_rt_period|cpu_rt_runtime|c|cpu_shares|cpus|cpuset_cpus|cpuset_mems|detach_keys|disable_content_trust|domainname|entrypoint|gpus|health_cmd|health_interval|health_retries|health_start_period|health_timeout|h|hostname|ip|ip6|ipc|isolation|kernel_memory|log_driver|mac_address|m|memory|memory_reservation|memory_swap|memory_swappiness|mount|name|network|no_healthcheck|oom_kill_disable|oom_score_adj|pid|pids_limit|restart|runtime|shm_size|sig_proxy|stop_signal|stop_timeout|ulimit|u|user|userns|uts|volume_driver|w|workdir|'
  local key_abb = {net='network',a='attach',c='cpu-shares',d='detach',e='env',h='hostname',i='interactive',l='label',m='memory',p='publish',P='publish_all',t='tty',u='user',v='volume',w='workdir'}
  local key_with_list = '|sysctl|add_host|a|attach|blkio_weight_device|cap_add|cap_drop|device|device_cgroup_rule|device_read_bps|device_read_iops|device_write_bps|device_write_iops|dns|dns_option|dns_search|e|env|env_file|expose|group_add|l|label|label_file|link|link_local_ip|log_driver|log_opt|network_alias|p|publish|security_opt|storage_opt|tmpfs|v|volume|volumes_from|'
  local key = nil
  local _key = nil
  local val = nil
  local is_cmd = false

  cmd_line = cmd_line:match("^DOCKERCLI%s+(.+)")
  for w in cmd_line:gmatch("[^%s]+") do
    if w =='\\' then
    elseif not key and not _key and not is_cmd then
      --key=val
      key, val = w:match("^%-%-([%lP%-]-)=(.+)")
      if not key then
        --key val
        key = w:match("^%-%-([%lP%-]+)")
        if not key then
          -- -v val
          key = w:match("^%-([%lP%-]+)")
          if key then
            -- for -dit
            if key:match("i") or key:match("t") or key:match("d") then
              if key:match("i") then
                config[key_abb["i"]] = true
                key:gsub("i", "")
              end
              if key:match("t") then
                config[key_abb["t"]] = true
                key:gsub("t", "")
              end
              if key:match("d") then
                config[key_abb["d"]] = true
                key:gsub("d", "")
              end
              if key:match("P") then
                config[key_abb["P"]] = true
                key:gsub("P", "")
              end
              if key == "" then key = nil end
            end
          end
        end
      end
      if key then
        key = key:gsub("-","_")
        key = key_abb[key] or key
        if key_no_val:match("|"..key.."|") then
          config[key] = true
          val = nil
          key = nil
        elseif key_with_val:match("|"..key.."|") then
          -- if key == "cap_add" then config.privileged = true end
        else
          key = nil
          val = nil
        end
      else
        config.image = w
        key = nil
        val = nil
        is_cmd = true
      end
    elseif (key or _key) and not is_cmd then
      if key == "mount" then
        -- we need resolve mount options here
        -- type=bind,source=/source,target=/app
        local _type = w:match("^type=([^,]+),") or "bind"
        local source =  (_type ~= "tmpfs") and (w:match("source=([^,]+),") or  w:match("src=([^,]+),")) or ""
        local target =  w:match(",target=([^,]+)") or  w:match(",dst=([^,]+)") or w:match(",destination=([^,]+)") or ""
        local ro = w:match(",readonly") and "ro" or nil
        if source and target then
          if _type ~= "tmpfs" then
            -- bind or volume
            local bind_propagation = (_type == "bind") and w:match(",bind%-propagation=([^,]+)") or nil
            val = source..":"..target .. ((ro or bind_propagation) and (":" .. (ro and ro or "") .. (((ro and bind_propagation) and "," or "") .. (bind_propagation and bind_propagation or ""))or ""))
          else
            -- tmpfs
            local tmpfs_mode = w:match(",tmpfs%-mode=([^,]+)") or nil
            local tmpfs_size = w:match(",tmpfs%-size=([^,]+)") or nil
            key = "tmpfs"
            val = target .. ((tmpfs_mode or tmpfs_size) and (":" .. (tmpfs_mode and ("mode=" .. tmpfs_mode) or "") .. ((tmpfs_mode and tmpfs_size) and "," or "") .. (tmpfs_size and ("size=".. tmpfs_size) or "")) or "")
            if not config[key] then config[key] = {} end
            table.insert( config[key], val )
            key = nil
            val = nil
          end
        end
      else
        val = w
      end
    elseif is_cmd then
      config["command"] = (config["command"] and (config["command"] .. " " )or "")  .. w
    end
    if (key or _key) and val then
      key = _key or key
      if key_with_list:match("|"..key.."|") then
        if not config[key] then config[key] = {} end
        if _key then
          config[key][#config[key]] = config[key][#config[key]] .. " " .. w
        else
          table.insert( config[key], val )
        end
        if is_quot_complete(config[key][#config[key]]) then
          -- clear quotation marks
          config[key][#config[key]] = config[key][#config[key]]:gsub("[\"\']", "")
          _key = nil
        else
          _key = key
        end
      else
        config[key] = (config[key] and (config[key] .. " ") or "") .. val
        if is_quot_complete(config[key]) then
          -- clear quotation marks
          config[key] = config[key]:gsub("[\"\']", "")
          _key = nil
        else
          _key = key
        end
      end
      key = nil<commit_msg>luci-app-dockerman: cbi/newcontainer refactoring and update partial coding style<commit_after>--[[
LuCI - Lua Configuration Interface
Copyright 2019 lisaac <https://github.com/lisaac/luci-app-dockerman>
]]--

require "luci.util"
local uci = luci.model.uci.cursor()
local docker = require "luci.model.docker"
local dk = docker.new()
local cmd_line = table.concat(arg, '/')
local create_body = {}

local images = dk.images:list().body
local networks = dk.networks:list().body
local containers = dk.containers:list({query = {all=true}}).body

local is_quot_complete = function(str)
  require "math"
  if not str then return true end
  local num = 0, w
  for w in str:gmatch("\"") do
    num = num + 1
  end
  if math.fmod(num, 2) ~= 0 then return false end
  num = 0
  for w in str:gmatch("\'") do
    num = num + 1
  end
  if math.fmod(num, 2) ~= 0 then return false end
  return true
end

function contains(list, x)
	for _, v in pairs(list) do
		if v == x then
			return true
		end
	end
	return false
end

local resolve_cli = function(cmd_line)
	local config = {
		advance = 1
	}

	local key_no_val = {
		't',
		'd',
		'i',
		'tty',
		'rm',
		'read_only',
		'interactive',
		'init',
		'help',
		'detach',
		'privileged',
		'P',
		'publish_all',
	}

	local key_with_val = {
		'sysctl',
		'add_host',
		'a',
		'attach',
		'blkio_weight_device',
		'cap_add',
		'cap_drop',
		'device',
		'device_cgroup_rule',
		'device_read_bps',
		'device_read_iops',
		'device_write_bps',
		'device_write_iops',
		'dns',
		'dns_option',
		'dns_search',
		'e',
		'env',
		'env_file',
		'expose',
		'group_add',
		'l',
		'label',
		'label_file',
		'link',
		'link_local_ip',
		'log_driver',
		'log_opt',
		'network_alias',
		'p',
		'publish',
		'security_opt',
		'storage_opt',
		'tmpfs',
		'v',
		'volume',
		'volumes_from',
		'blkio_weight',
		'cgroup_parent',
		'cidfile',
		'cpu_period',
		'cpu_quota',
		'cpu_rt_period',
		'cpu_rt_runtime',
		'c',
		'cpu_shares',
		'cpus',
		'cpuset_cpus',
		'cpuset_mems',
		'detach_keys',
		'disable_content_trust',
		'domainname',
		'entrypoint',
		'gpus',
		'health_cmd',
		'health_interval',
		'health_retries',
		'health_start_period',
		'health_timeout',
		'h',
		'hostname',
		'ip',
		'ip6',
		'ipc',
		'isolation',
		'kernel_memory',
		'log_driver',
		'mac_address',
		'm',
		'memory',
		'memory_reservation',
		'memory_swap',
		'memory_swappiness',
		'mount',
		'name',
		'network',
		'no_healthcheck',
		'oom_kill_disable',
		'oom_score_adj',
		'pid',
		'pids_limit',
		'restart',
		'runtime',
		'shm_size',
		'sig_proxy',
		'stop_signal',
		'stop_timeout',
		'ulimit',
		'u',
		'user',
		'userns',
		'uts',
		'volume_driver',
		'w',
		'workdir'
	}

	local key_abb = {
		net='network',
		a='attach',
		c='cpu-shares',
		d='detach',
		e='env',
		h='hostname',
		i='interactive',
		l='label',
		m='memory',
		p='publish',
		P='publish_all',
		t='tty',
		u='user',
		v='volume',
		w='workdir'
	}

	local key_with_list = {
		'sysctl',
		'add_host',
		'a',
		'attach',
		'blkio_weight_device',
		'cap_add',
		'cap_drop',
		'device',
		'device_cgroup_rule',
		'device_read_bps',
		'device_read_iops',
		'device_write_bps',
		'device_write_iops',
		'dns',
		'dns_optiondns_search',
		'e',
		'env',
		'env_file',
		'expose',
		'group_add',
		'l',
		'label',
		'label_file',
		'link',
		'link_local_ip',
		'log_driver',
		'log_opt',
		'network_alias',
		'p',
		'publish',
		'security_opt',
		'storage_opt',
		'tmpfs',
		'v',
		'volume',
		'volumes_from',
	}

  local key = nil
  local _key = nil
  local val = nil
  local is_cmd = false

  cmd_line = cmd_line:match("^DOCKERCLI%s+(.+)")
  for w in cmd_line:gmatch("[^%s]+") do
    if w =='\\' then
    elseif not key and not _key and not is_cmd then
      --key=val
      key, val = w:match("^%-%-([%lP%-]-)=(.+)")
      if not key then
        --key val
        key = w:match("^%-%-([%lP%-]+)")
        if not key then
          -- -v val
          key = w:match("^%-([%lP%-]+)")
          if key then
            -- for -dit
            if key:match("i") or key:match("t") or key:match("d") then
              if key:match("i") then
                config[key_abb["i"]] = true
                key:gsub("i", "")
              end
              if key:match("t") then
                config[key_abb["t"]] = true
                key:gsub("t", "")
              end
              if key:match("d") then
                config[key_abb["d"]] = true
                key:gsub("d", "")
              end
              if key:match("P") then
                config[key_abb["P"]] = true
                key:gsub("P", "")
              end
              if key == "" then key = nil end
            end
          end
        end
      end
      if key then
        key = key:gsub("-","_")
        key = key_abb[key] or key
        if contains(key_no_val, key) then
          config[key] = true
          val = nil
          key = nil
        elseif contains(key_with_val, key) then
          -- if key == "cap_add" then config.privileged = true end
        else
          key = nil
          val = nil
        end
      else
        config.image = w
        key = nil
        val = nil
        is_cmd = true
      end
    elseif (key or _key) and not is_cmd then
      if key == "mount" then
        -- we need resolve mount options here
        -- type=bind,source=/source,target=/app
        local _type = w:match("^type=([^,]+),") or "bind"
        local source =  (_type ~= "tmpfs") and (w:match("source=([^,]+),") or  w:match("src=([^,]+),")) or ""
        local target =  w:match(",target=([^,]+)") or  w:match(",dst=([^,]+)") or w:match(",destination=([^,]+)") or ""
        local ro = w:match(",readonly") and "ro" or nil
        if source and target then
          if _type ~= "tmpfs" then
            -- bind or volume
            local bind_propagation = (_type == "bind") and w:match(",bind%-propagation=([^,]+)") or nil
            val = source..":"..target .. ((ro or bind_propagation) and (":" .. (ro and ro or "") .. (((ro and bind_propagation) and "," or "") .. (bind_propagation and bind_propagation or ""))or ""))
          else
            -- tmpfs
            local tmpfs_mode = w:match(",tmpfs%-mode=([^,]+)") or nil
            local tmpfs_size = w:match(",tmpfs%-size=([^,]+)") or nil
            key = "tmpfs"
            val = target .. ((tmpfs_mode or tmpfs_size) and (":" .. (tmpfs_mode and ("mode=" .. tmpfs_mode) or "") .. ((tmpfs_mode and tmpfs_size) and "," or "") .. (tmpfs_size and ("size=".. tmpfs_size) or "")) or "")
            if not config[key] then config[key] = {} end
            table.insert( config[key], val )
            key = nil
            val = nil
          end
        end
      else
        val = w
      end
    elseif is_cmd then
      config["command"] = (config["command"] and (config["command"] .. " " )or "")  .. w
    end
    if (key or _key) and val then
      key = _key or key
      if contains(key_with_list, key) then
        if not config[key] then config[key] = {} end
        if _key then
          config[key][#config[key]] = config[key][#config[key]] .. " " .. w
        else
          table.insert( config[key], val )
        end
        if is_quot_complete(config[key][#config[key]]) then
          -- clear quotation marks
          config[key][#config[key]] = config[key][#config[key]]:gsub("[\"\']", "")
          _key = nil
        else
          _key = key
        end
      else
        config[key] = (config[key] and (config[key] .. " ") or "") .. val
        if is_quot_complete(config[key]) then
          -- clear quotation marks
          config[key] = config[key]:gsub("[\"\']", "")
          _key = nil
        else
          _key = key
        end
      end
      key = nil
{'fraction_non_alphanumeric': 0.16683909235119662, 'fraction_numerical': 0.0019311676667356369, 'mean_word_length': 2.4021586109807602, 'pattern_counts': {'":': 6, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1567724', 'n_tokens_mistral': 5373, 'n_tokens_neox': 5143, 'n_words': 1139}