Using modified addxml with serialize problem

Posted by Mason on Sun 09 Jun 2013 11:36 AM — 3 posts, 13,113 views.

#0
This plugin has a table( a list of aliases for sorting equipment and what bank its stroed at) a few aliases to generators new aliases. and for testing some of these functions. Those are all working properly so I didn't include them.

My main problem is getting the tables to save properly.

Using serialize,save() either: Saves the aliases without a send field, or after I modified some addxml.lua functions and including them worked but showed a warning about a clipboard argument not being used for each alias processed. Not a big deal but spammy every time the plugin is loaded/saved.

Everything I have tried to get the table to save using my modified addxml.save() either: returned string or nil when expecting table., or Renamed the table so the plugin fails on reload. or Completely overwrites the table with last alias processed. and I even caused a crash with an accidentally loop. any help at all will be greatly appreciated.



<script>
<![CDATA[

require "serialize"
require "tprint"

function tweak (t)
	assert (type (t) == "table", "Table must be supplied to save an alias")
	for text, info in pairs (t) do
		if text == "name" then
			tprint(alias_save(t.name))
        --here is where I was trying to convert to save
           --needs to save as vic[#vic+1]
		end
	end
end

function OnPluginInstall ()
	vic = {}
	assert (loadstring (GetVariable("newsets") or  GetVariable("oldsets"))) ()
	loadtable()
end -- function OnPluginInstall

function testtable ()
	for text, info in ipairs (vic) do
	tweak(info)
	end -- for
end

function loadtable ()
	if vic ~= nil then 
		if type(vic) == "table" then
			for text, info in ipairs (vic) do
				alias_create(info)
			end
		end
	else
		print("Test Tables Loaded <<<tables are empty>>>")
		vic = {}
	end
end 

function cleartable (tab)
	assert(type (tab) == "table", "ERROR: That was not a table you tried to 

clear")
	if tab ~= nil then
		tab = {}
	end
end

function OnPluginSaveState ()		
		for text, info in ipairs (vic) do
			tweak (info)
			tprint (info)
		end 
end

function savetable ()
	SaveState()
end 

function printtable (name, line, wildcards)
		for text, info in pairs (vic) do
			print(text)
			tprint(info)
		end -- for
	print("<<<<<<<<<<END OF ALIASES>>>>>>>>>>>>>>>>>")
end

function addtotable (name, line, wildcards)
	local gear = Trim(wildcards [3] or "")
	local target = Trim(wildcards [1] or "")
	local location = Trim(wildcards [2] or "")
	if room ~= nil then
		vic	[#vic + 1] = {
			match = "wear fset "..target,
			send = "get ".. gear .." from "..location,
			sequence = 100,
			keep_evaluating = true,
                        enabled = true,
			name = gear,
			send_to = 10,
						}
		alias_create {  
			match = "wear fset "..target,
			send = "get ".. gear .." from "..location,
			sequence = 100,
			keep_evaluating = true,
			enabled = true,
			name = gear,
			send_to = 10,
				 }
		ColourNote ("green", "black", "Added alias to match on 'wear fset "..target.."', sending 'get ".. gear .." from "..location.."'")

	end
end -- addtotable

xml_replace = { 
   ["<"] = "&lt;",
   [">"] = "&gt;",
   ["&"] = "&amp;",
   ['"'] = "&quot;",
   }

function fixhtml (s)
  return (string.gsub (tostring (s), '[<>&"]', 
    function (str)
      return xml_replace [str] or str
    end ))
end -- fixhtml

function alias_create (t)
	add_alias (t, "alias", "aliases")
	if t.name and t.script then
		SetAliasOption (t.name, "script", t.script)
	end
end 

function add_alias (t, datam, data)
	assert (type (t) == "table", "Table must be supplied to add a " .. datam)
	local k, v
	local xml = {}
	local send = fixhtml (t.send)
	t.send = nil --removing this and using serialize.save() works but spammy 
	
         for k, v in pairs (t) do
		if v == true then
			v = "y"
		elseif v == false then
			v = "n"
		end
		table.insert (xml, k .. '="' .. fixhtml (v) .. '"')
	end 
	assert (ImportXML (string.format (
          "<%s><%s %s ><send>%s</send></%s></%s>",
             data,   
             datam,    
             table.concat (xml, "\n"),  
             send,     
             datam,    
             data)   
         ) == 1, "Import of " .. datam .. " failed") 
end 

function alias_save (name)

  local itemtype = 1
  local xml = ExportXML (itemtype, name)
  
  assert (xml ~= "", "Can't find that alias : " .. name)
  local xmlnodes = assert (utils.xmlread (xml), "Bad XML")
  local result = xmlnodes.nodes [1].nodes [1].attributes
                   
  if xmlnodes.nodes [1].nodes [1].nodes then
    if xmlnodes.nodes [1].nodes [1].nodes [1].name == "send" then
       result.send = xmlnodes.nodes [1].nodes [1].nodes [1].content
    end 
  end 
  
  return result
end 
]]>
</script>



edited to highlight and fix some spacing

[EDIT] Code tags added.
Amended on Sun 09 Jun 2013 10:07 PM by Nick Gammon
Australia Forum Administrator #1
What you have there looks too complex. I did a test here:


<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>

<muclient>
<plugin
   name="Add_Alias_Test"
   author="Nick Gammon"
   id="b920d042723a654dd203dea6"
   language="Lua"
   purpose="Adds an alias, serializes it within plugin"
   save_state="y"
   date_written="2013-06-10 07:13:27"
   requires="4.80"
   version="1.0"
   >
</plugin>

<aliases>
  <alias
   match="^\#alias \{(?P&lt;match&gt;[A-Za-z]+)\} \{(?P&lt;send&gt;.+)\}$"
   enabled="y"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>

  addxml.alias {  
      match = "^%&lt;match&gt;(?P&lt;target&gt; [A-Za-z]{1,}){0,1}$", 
      regexp = true,
      send = "%&lt;send&gt;%%&lt;target&gt;",
      sequence = 100,
      enabled = true,
      name = "%&lt;match&gt;",
      user = 1,
    }
 ColourNote ("white", "green",
                 "Alias '%&lt;match&gt;' added which sends '%&lt;send&gt;'")
</send>
  </alias>
</aliases>

<script>
<![CDATA[
require "addxml"
require "serialize"  -- needed to serialize table to string

-- on plugin install, convert variable into Lua table

function OnPluginInstall ()
  my_aliases = "" 
  assert (loadstring (GetVariable ("my_aliases") or "")) ()
  local result = ImportXML (my_aliases)
  print ("Imported", result, "alias(s) from plugin state file")
end -- function OnPluginInstall

-- on saving state, convert Lua variable into string variable

function OnPluginSaveState ()

  -- all of the aliases
  local allAliases = { }
  
  -- get list
  local al = GetAliasList()
  if al then
    for k, v in ipairs (al) do 
      -- only do ones we added
      if GetAliasInfo (v, 23) == 1 then
        table.insert (allAliases, ExportXML (1, v))
      end -- if added by us
    end  -- for
  end -- if we have any aliases

  SetVariable ("my_aliases", "my_aliases = " .. serialize.save_simple (table.concat (allAliases, " ")))
end -- function OnPluginSaveState

]]>
</script> 

</muclient>


The alias in the plugin is for testing. It adds aliases (so you now have more plugins than the alias started with).

eg,


#alias {foo} {dance}
#alias {bar} {laugh}


The added aliases have "1" in the alias "user" field to distinguish them from the existing plugin's aliases. Then in the OnPluginSaveState function we find all such aliases, and convert them to XML.

The serialize.save_simple function is then used to convert the concatenated XML into a single variable "my_aliases" which ends up in the state file.

Then OnPluginInstall is used to get that single variable, and import it. A single line is all that is required, not all that delving into the XML table.


  local result = ImportXML (my_aliases)
  print ("Imported", result, "alias(s) from plugin state file")

Amended on Sun 09 Jun 2013 11:03 PM by Nick Gammon
#2
Thank you for such a simple solution Nick I'm new to lua and had made most of the functions i was trying to use before discovering the lua modules while searching the forums and tried to make my old functions work similarly instead of just starting over, and the whole script just kinda snowballed trying to get it working from there on.