X-Git-Url: https://git.enpas.org/?a=blobdiff_plain;f=tools%2Fejabberdsql2prosody.lua;h=21d480ea174fa534f3374328884e7062051c0cbd;hb=cb694b082834d49b72ceb21a42ade9b39ab9b83b;hp=90990b64245b7a9af566578677b76436cafaade5;hpb=bacb6be1d13babbbdd2ff3d8c4fca1f4d0ccf48e;p=prosody.git diff --git a/tools/ejabberdsql2prosody.lua b/tools/ejabberdsql2prosody.lua index 90990b64..21d480ea 100644 --- a/tools/ejabberdsql2prosody.lua +++ b/tools/ejabberdsql2prosody.lua @@ -136,7 +136,14 @@ local function readFile(filename) while true do local tname, tuples = readInsert(); if tname then - t[tname] = tuples; + if t[name] then + local t_name = t[name]; + for i=1,#tuples do + table.insert(t_name, tuples[i]); + end + else + t[tname] = tuples; + end elseif peek() == nil then break; end @@ -149,6 +156,58 @@ return readFile(filename); ------ end +-- XML parser +local parse_xml = (function() + local entity_map = setmetatable({ + ["amp"] = "&"; + ["gt"] = ">"; + ["lt"] = "<"; + ["apos"] = "'"; + ["quot"] = "\""; + }, {__index = function(_, s) + if s:sub(1,1) == "#" then + if s:sub(2,2) == "x" then + return string.char(tonumber(s:sub(3), 16)); + else + return string.char(tonumber(s:sub(2))); + end + end + end + }); + local function xml_unescape(str) + return (str:gsub("&(.-);", entity_map)); + end + local function parse_tag(s) + local name,sattr=(s):gmatch("([^%s]+)(.*)")(); + local attr = {}; + for a,b in (sattr):gmatch("([^=%s]+)=['\"]([^'\"]*)['\"]") do attr[a] = xml_unescape(b); end + return name, attr; + end + return function(xml) + local stanza = st.stanza("root"); + local regexp = "<([^>]*)>([^<]*)"; + for elem, text in xml:gmatch(regexp) do + if elem:sub(1,1) == "!" or elem:sub(1,1) == "?" then -- neglect comments and processing-instructions + elseif elem:sub(1,1) == "/" then -- end tag + elem = elem:sub(2); + stanza:up(); -- TODO check for start-end tag name match + elseif elem:sub(-1,-1) == "/" then -- empty tag + elem = elem:sub(1,-2); + local name,attr = parse_tag(elem); + stanza:tag(name, attr):up(); + else -- start tag + local name,attr = parse_tag(elem); + stanza:tag(name, attr); + end + if #text ~= 0 then -- text + stanza:text(xml_unescape(text)); + end + end + return stanza.tags[1]; + end +end)(); +-- end of XML parser + local arg, host = ...; local help = "/? -? ? /h -h /help -help --help"; if not(arg and host) or help:find(arg, 1, true) then @@ -178,9 +237,12 @@ local t = parseFile(arg); for name, data in pairs(t) do local m = map[name]; if m then + if #data > 0 and #data[1] ~= #m then + print("[warning] expected "..#m.." columns for table `"..name.."`, found "..#data[1]); + end for i=1,#data do local row = data[i]; - for j=1,#row do + for j=1,#m do row[m[j]] = row[j]; row[j] = nil; end @@ -211,7 +273,7 @@ end function roster_group(node, host, jid, group) local roster = dm.load(node, host, "roster") or {}; local item = roster[jid]; - if not item then print("Warning: No roster item "..jid.." for user "..user..", can't put in group "..group); return; end + if not item then print("Warning: No roster item "..jid.." for user "..node..", can't put in group "..group); return; end item.groups[group] = true; local ret, err = dm.store(node, host, "roster", roster); print("["..(err or "success").."] roster-group: " ..node.."@"..host.." - "..jid.." - "..group); @@ -238,6 +300,9 @@ for i, row in ipairs(t["rosterusers"] or NULL) do elseif ask == "I" then roster_pending(node, host, contact); ask = nil; + elseif ask == "B" then + roster_pending(node, host, contact); + ask = "subscribe"; else error("Unknown ask type: "..ask); end local item = {name = name, ask = ask, subscription = subscription, groups = {}}; roster(node, host, contact, item); @@ -245,3 +310,7 @@ end for i, row in ipairs(t["rostergroups"] or NULL) do roster_group(row.username, host, row.jid, row.grp); end +for i, row in ipairs(t["vcard"] or NULL) do + local ret, err = dm.store(row.username, host, "vcard", st.preserialize(parse_xml(row.vcard))); + print("["..(err or "success").."] vCard: "..row.username.."@"..host); +end