2 local st = require "util.stanza";
\r
4 local function getXml(user, host)
\r
5 local jid = user.."@"..host;
\r
6 local path = "data/"..jid..".xml";
\r
7 local f = io.open(path);
\r
8 if not f then return; end
\r
9 local s = f:read("*a");
\r
10 return parse_xml_real(s);
\r
12 local function setXml(user, host, xml)
\r
13 local jid = user.."@"..host;
\r
14 local path = "data/"..jid..".xml";
\r
16 local f = io.open(path, "w");
\r
17 if not f then return; end
\r
18 local s = tostring(xml);
\r
23 return os.remove(path);
\r
26 local function getUserElement(xml)
\r
27 if xml and xml.name == "server-data" then
\r
28 local host = xml.tags[1];
\r
29 if host and host.name == "host" then
\r
30 local user = host.tags[1];
\r
31 if user and user.name == "user" then
\r
37 local function createOuterXml(user, host)
\r
38 return st.stanza("server-data", {xmlns='http://www.xmpp.org/extensions/xep-0227.html#ns'})
\r
39 :tag("host", {jid=host})
\r
40 :tag("user", {name = user});
\r
42 local function removeFromArray(array, value)
\r
43 for i,item in ipairs(array) do
\r
44 if item == value then
\r
45 table.remove(array, i);
\r
50 local function removeStanzaChild(s, child)
\r
51 removeFromArray(s.tags, child);
\r
52 removeFromArray(s, child);
\r
55 local handlers = {};
\r
57 handlers.accounts = {
\r
58 get = function(self, user)
\r
59 local user = getUserElement(getXml(user, self.host));
\r
60 if user and user.attr.password then
\r
61 return { password = user.attr.password };
\r
64 set = function(self, user, data)
\r
65 if data and data.password then
\r
66 local xml = getXml(user, self.host);
\r
67 if not xml then xml = createOuterXml(user, self.host); end
\r
68 local usere = getUserElement(xml);
\r
69 usere.attr.password = data.password;
\r
70 return setXml(user, self.host, xml);
\r
72 return setXml(user, self.host, nil);
\r
77 get = function(self, user)
\r
78 local user = getUserElement(getXml(user, self.host));
\r
80 local vcard = user:get_child("vCard", 'vcard-temp');
\r
82 return st.preserialize(vcard);
\r
86 set = function(self, user, data)
\r
87 local xml = getXml(user, self.host);
\r
88 local usere = xml and getUserElement(xml);
\r
90 local vcard = usere:get_child("vCard", 'vcard-temp');
\r
92 removeStanzaChild(usere, vcard);
\r
93 elseif not data then
\r
97 vcard = st.deserialize(data);
\r
98 usere:add_child(vcard);
\r
100 return setXml(user, self.host, xml);
\r
105 handlers.private = {
\r
106 get = function(self, user)
\r
107 local user = getUserElement(getXml(user, self.host));
\r
109 local private = user:get_child("query", "jabber:iq:private");
\r
112 for _, tag in ipairs(private.tags) do
\r
113 r[tag.name..":"..tag.attr.xmlns] = st.preserialize(tag);
\r
119 set = function(self, user, data)
\r
120 local xml = getXml(user, self.host);
\r
121 local usere = xml and getUserElement(xml);
\r
123 local private = usere:get_child("query", 'jabber:iq:private');
\r
124 if private then removeStanzaChild(usere, private); end
\r
125 if data and next(data) ~= nil then
\r
126 private = st.stanza("query", {xmlns='jabber:iq:private'});
\r
127 for _,tag in pairs(data) do
\r
128 private:add_child(st.deserialize(tag));
\r
130 usere:add_child(private);
\r
132 return setXml(user, self.host, xml);
\r
138 -----------------------------
\r
140 driver.__index = driver;
\r
142 function driver:open(host, datastore, typ)
\r
143 local cache_key = host.." "..datastore;
\r
144 if self.ds_cache[cache_key] then return self.ds_cache[cache_key]; end
\r
145 local instance = setmetatable({}, self);
\r
146 instance.host = host;
\r
147 instance.datastore = datastore;
\r
148 local handler = handlers[datastore];
\r
149 if not handler then return nil; end
\r
150 for key,val in pairs(handler) do
\r
151 instance[key] = val;
\r
153 if instance.init then instance:init(); end
\r
154 self.ds_cache[cache_key] = instance;
\r
158 -----------------------------
\r
162 local instance = setmetatable({}, driver);
\r
163 instance.__index = instance;
\r
164 instance.ds_cache = {};
\r