Mercurial > prosody-modules
comparison mod_storage_xmlarchive/mod_storage_xmlarchive.lua @ 2813:e5ce64aee4ac
mod_storage_xmlarchive: Pass the hostname into the archive object to make it more self-contained
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Thu, 09 Nov 2017 13:34:05 +0100 |
| parents | 1b081c8fc1d9 |
| children | 1ffbd73c54ba |
comparison
equal
deleted
inserted
replaced
| 2812:fd4a5ba12fa2 | 2813:e5ce64aee4ac |
|---|---|
| 35 | 35 |
| 36 username = username or "@"; | 36 username = username or "@"; |
| 37 data = tostring(data) .. "\n"; | 37 data = tostring(data) .. "\n"; |
| 38 | 38 |
| 39 local day = dt.date(when); | 39 local day = dt.date(when); |
| 40 local ok, err = dm.append_raw(username.."@"..day, module.host, self.store, "xml", data); | 40 local ok, err = dm.append_raw(username.."@"..day, self.host, self.store, "xml", data); |
| 41 if not ok then | 41 if not ok then |
| 42 return nil, err; | 42 return nil, err; |
| 43 end | 43 end |
| 44 | 44 |
| 45 -- If the day-file is missing then we need to add it to the list of days | 45 -- If the day-file is missing then we need to add it to the list of days |
| 46 local first_of_day = not lfs.attributes(dm.getpath(username .. "@" .. day, module.host, self.store, "list")); | 46 local first_of_day = not lfs.attributes(dm.getpath(username .. "@" .. day, self.host, self.store, "list")); |
| 47 | 47 |
| 48 local offset = ok and err or 0; | 48 local offset = ok and err or 0; |
| 49 | 49 |
| 50 local id = day .. "-" .. hmac_sha256(username.."@"..day.."+"..offset, data, true):sub(-16); | 50 local id = day .. "-" .. hmac_sha256(username.."@"..day.."+"..offset, data, true):sub(-16); |
| 51 ok, err = dm.list_append(username.."@"..day, module.host, self.store, | 51 ok, err = dm.list_append(username.."@"..day, self.host, self.store, |
| 52 { id = id, when = dt.datetime(when), with = with, offset = offset, length = #data }); | 52 { id = id, when = dt.datetime(when), with = with, offset = offset, length = #data }); |
| 53 if ok and first_of_day then | 53 if ok and first_of_day then |
| 54 ok, err = dm.list_append(username, module.host, self.store, day); | 54 ok, err = dm.list_append(username, self.host, self.store, day); |
| 55 end | 55 end |
| 56 if not ok then | 56 if not ok then |
| 57 return nil, err; | 57 return nil, err; |
| 58 end | 58 end |
| 59 return id; | 59 return id; |
| 63 dates = dates or self:dates(username) or empty; | 63 dates = dates or self:dates(username) or empty; |
| 64 local date = id:sub(1, 10); | 64 local date = id:sub(1, 10); |
| 65 for d = 1, #dates do | 65 for d = 1, #dates do |
| 66 if date == dates[d] then | 66 if date == dates[d] then |
| 67 module:log("debug", "Loading items from %s", dates[d]); | 67 module:log("debug", "Loading items from %s", dates[d]); |
| 68 local items = dm.list_load(username .. "@" .. dates[d], module.host, self.store) or empty; | 68 local items = dm.list_load(username .. "@" .. dates[d], self.host, self.store) or empty; |
| 69 for i = 1, #items do | 69 for i = 1, #items do |
| 70 if items[i].id == id then | 70 if items[i].id == id then |
| 71 return d, i, items; | 71 return d, i, items; |
| 72 end | 72 end |
| 73 end | 73 end |
| 157 xmlfile:close(); | 157 xmlfile:close(); |
| 158 xmlfile = nil; | 158 xmlfile = nil; |
| 159 end | 159 end |
| 160 if not xmlfile then | 160 if not xmlfile then |
| 161 date_open = date; | 161 date_open = date; |
| 162 local filename = dm.getpath(username .. "@" .. date, module.host, self.store, "xml"); | 162 local filename = dm.getpath(username .. "@" .. date, self.host, self.store, "xml"); |
| 163 local ferr; | 163 local ferr; |
| 164 xmlfile, ferr = io.open(filename); | 164 xmlfile, ferr = io.open(filename); |
| 165 if not xmlfile then | 165 if not xmlfile then |
| 166 module:log("error", "Error: %s", ferr); | 166 module:log("error", "Error: %s", ferr); |
| 167 return nil, ferr; | 167 return nil, ferr; |
| 179 for d = start_day, last_day, step do | 179 for d = start_day, last_day, step do |
| 180 local date = dates[d]; | 180 local date = dates[d]; |
| 181 if not items then | 181 if not items then |
| 182 module:log("debug", "Loading items from %s", date); | 182 module:log("debug", "Loading items from %s", date); |
| 183 start_day = d; | 183 start_day = d; |
| 184 items = dm.list_load(username .. "@" .. date, module.host, self.store) or empty; | 184 items = dm.list_load(username .. "@" .. date, self.host, self.store) or empty; |
| 185 if not rev then | 185 if not rev then |
| 186 first_item, last_item = 1, #items; | 186 first_item, last_item = 1, #items; |
| 187 else | 187 else |
| 188 first_item, last_item = #items, 1; | 188 first_item, last_item = #items, 1; |
| 189 end | 189 end |
| 215 | 215 |
| 216 local data = read_xml(date, item.offset, item.length); | 216 local data = read_xml(date, item.offset, item.length); |
| 217 if not data then return end | 217 if not data then return end |
| 218 local ok, err = stream:feed(data); | 218 local ok, err = stream:feed(data); |
| 219 if not ok then | 219 if not ok then |
| 220 module:log("warn", "Parse error in %s@%s/%s/%q[%d]: %s", username, module.host, self.store, i, err); | 220 module:log("warn", "Parse error in %s@%s/%s/%q[%d]: %s", username, self.host, self.store, i, err); |
| 221 reset_stream(); | 221 reset_stream(); |
| 222 end | 222 end |
| 223 if result then | 223 if result then |
| 224 local stanza = result; | 224 local stanza = result; |
| 225 result = nil; | 225 result = nil; |
| 255 if dates[d] >= before then | 255 if dates[d] >= before then |
| 256 table.insert(remaining_dates, dates[d]); | 256 table.insert(remaining_dates, dates[d]); |
| 257 end | 257 end |
| 258 end | 258 end |
| 259 table.sort(remaining_dates); | 259 table.sort(remaining_dates); |
| 260 local ok, err = dm.list_store(username, module.host, self.store, remaining_dates); | 260 local ok, err = dm.list_store(username, self.host, self.store, remaining_dates); |
| 261 if not ok then return ok, err; end | 261 if not ok then return ok, err; end |
| 262 for d = 1, #dates do | 262 for d = 1, #dates do |
| 263 if dates[d] < before then | 263 if dates[d] < before then |
| 264 os.remove(dm.getpath(username .. "@" .. dates[d], module.host, self.store, "list")); | 264 os.remove(dm.getpath(username .. "@" .. dates[d], self.host, self.store, "list")); |
| 265 os.remove(dm.getpath(username .. "@" .. dates[d], module.host, self.store, "xml")); | 265 os.remove(dm.getpath(username .. "@" .. dates[d], self.host, self.store, "xml")); |
| 266 end | 266 end |
| 267 end | 267 end |
| 268 return true; | 268 return true; |
| 269 end | 269 end |
| 270 | 270 |
| 271 function archive:dates(username) | 271 function archive:dates(username) |
| 272 return dm.list_load(username, module.host, self.store); | 272 return dm.list_load(username, self.host, self.store); |
| 273 end | 273 end |
| 274 | 274 |
| 275 local provider = {}; | 275 local provider = {}; |
| 276 function provider:open(store, typ) | 276 function provider:open(store, typ) |
| 277 if typ ~= "archive" then return nil, "unsupported-store"; end | 277 if typ ~= "archive" then return nil, "unsupported-store"; end |
| 278 return setmetatable({ store = store }, archive_mt); | 278 return setmetatable({ host = module.host, store = store }, archive_mt); |
| 279 end | 279 end |
| 280 | 280 |
| 281 function provider:purge(username) | 281 function provider:purge(username) |
| 282 local encoded_username = dm.path_encode((username or "@") .. "@"); | 282 local encoded_username = dm.path_encode((username or "@") .. "@"); |
| 283 local basepath = prosody.paths.data .. "/" .. dm.path_encode(module.host); | 283 local basepath = prosody.paths.data .. "/" .. dm.path_encode(module.host); |
