Software /
code /
prosody
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; |