Comparison

plugins/storage/xep227store.lib.lua @ 2678:c5882e2e12b5

mod_storage, plus a bit of SQL and XML.
author Waqas Hussain <waqas20@gmail.com>
date Fri, 19 Feb 2010 22:32:28 +0500
comparison
equal deleted inserted replaced
2677:467568f1117d 2678:c5882e2e12b5
1
2 local st = require "util.stanza";
3
4 local function getXml(user, host)
5 local jid = user.."@"..host;
6 local path = "data/"..jid..".xml";
7 local f = io.open(path);
8 if not f then return; end
9 local s = f:read("*a");
10 return parse_xml_real(s);
11 end
12 local function setXml(user, host, xml)
13 local jid = user.."@"..host;
14 local path = "data/"..jid..".xml";
15 if xml then
16 local f = io.open(path, "w");
17 if not f then return; end
18 local s = tostring(xml);
19 f:write(s);
20 f:close();
21 return true;
22 else
23 return os.remove(path);
24 end
25 end
26 local function getUserElement(xml)
27 if xml and xml.name == "server-data" then
28 local host = xml.tags[1];
29 if host and host.name == "host" then
30 local user = host.tags[1];
31 if user and user.name == "user" then
32 return user;
33 end
34 end
35 end
36 end
37 local function createOuterXml(user, host)
38 return st.stanza("server-data", {xmlns='http://www.xmpp.org/extensions/xep-0227.html#ns'})
39 :tag("host", {jid=host})
40 :tag("user", {name = user});
41 end
42 local function removeFromArray(array, value)
43 for i,item in ipairs(array) do
44 if item == value then
45 table.remove(array, i);
46 return;
47 end
48 end
49 end
50 local function removeStanzaChild(s, child)
51 removeFromArray(s.tags, child);
52 removeFromArray(s, child);
53 end
54
55 local handlers = {};
56
57 handlers.accounts = {
58 get = function(self, user)
59 local user = getUserElement(getXml(user, self.host));
60 if user and user.attr.password then
61 return { password = user.attr.password };
62 end
63 end;
64 set = function(self, user, data)
65 if data and data.password then
66 local xml = getXml(user, self.host);
67 if not xml then xml = createOuterXml(user, self.host); end
68 local usere = getUserElement(xml);
69 usere.attr.password = data.password;
70 return setXml(user, self.host, xml);
71 else
72 return setXml(user, self.host, nil);
73 end
74 end;
75 };
76 handlers.vcard = {
77 get = function(self, user)
78 local user = getUserElement(getXml(user, self.host));
79 if user then
80 local vcard = user:get_child("vCard", 'vcard-temp');
81 if vcard then
82 return st.preserialize(vcard);
83 end
84 end
85 end;
86 set = function(self, user, data)
87 local xml = getXml(user, self.host);
88 local usere = xml and getUserElement(xml);
89 if usere then
90 local vcard = usere:get_child("vCard", 'vcard-temp');
91 if vcard then
92 removeStanzaChild(usere, vcard);
93 elseif not data then
94 return true;
95 end
96 if data then
97 vcard = st.deserialize(data);
98 usere:add_child(vcard);
99 end
100 return setXml(user, self.host, xml);
101 end
102 return true;
103 end;
104 };
105 handlers.private = {
106 get = function(self, user)
107 local user = getUserElement(getXml(user, self.host));
108 if user then
109 local private = user:get_child("query", "jabber:iq:private");
110 if private then
111 local r = {};
112 for _, tag in ipairs(private.tags) do
113 r[tag.name..":"..tag.attr.xmlns] = st.preserialize(tag);
114 end
115 return r;
116 end
117 end
118 end;
119 set = function(self, user, data)
120 local xml = getXml(user, self.host);
121 local usere = xml and getUserElement(xml);
122 if usere then
123 local private = usere:get_child("query", 'jabber:iq:private');
124 if private then removeStanzaChild(usere, private); end
125 if data and next(data) ~= nil then
126 private = st.stanza("query", {xmlns='jabber:iq:private'});
127 for _,tag in pairs(data) do
128 private:add_child(st.deserialize(tag));
129 end
130 usere:add_child(private);
131 end
132 return setXml(user, self.host, xml);
133 end
134 return true;
135 end;
136 };
137
138 -----------------------------
139 local driver = {};
140 driver.__index = driver;
141
142 function driver:open(host, datastore, typ)
143 local cache_key = host.." "..datastore;
144 if self.ds_cache[cache_key] then return self.ds_cache[cache_key]; end
145 local instance = setmetatable({}, self);
146 instance.host = host;
147 instance.datastore = datastore;
148 local handler = handlers[datastore];
149 if not handler then return nil; end
150 for key,val in pairs(handler) do
151 instance[key] = val;
152 end
153 if instance.init then instance:init(); end
154 self.ds_cache[cache_key] = instance;
155 return instance;
156 end
157
158 -----------------------------
159 local _M = {};
160
161 function _M.new()
162 local instance = setmetatable({}, driver);
163 instance.__index = instance;
164 instance.ds_cache = {};
165 return instance;
166 end
167
168 return _M;