new storage and migration
This commit is contained in:
parent
2431495c99
commit
385d5cd4b7
6
api.lua
6
api.lua
@ -1,4 +1,3 @@
|
|||||||
mail.messages = {}
|
|
||||||
|
|
||||||
mail.registered_on_receives = {}
|
mail.registered_on_receives = {}
|
||||||
function mail.register_on_receive(func)
|
function mail.register_on_receive(func)
|
||||||
@ -12,15 +11,16 @@ function mail.send(src, dst, subject, body)
|
|||||||
minetest.log("action", "[mail] '" .. src .. "' sends mail to '" .. dst ..
|
minetest.log("action", "[mail] '" .. src .. "' sends mail to '" .. dst ..
|
||||||
"' with subject '" .. subject .. "' and body: '" .. body .. "'")
|
"' with subject '" .. subject .. "' and body: '" .. body .. "'")
|
||||||
|
|
||||||
mail.messages[dst] = mail.messages[dst] or {}
|
local messages = mail.getMessages(dst)
|
||||||
|
|
||||||
table.insert(mail.messages[dst], 1, {
|
table.insert(messages, 1, {
|
||||||
unread = true,
|
unread = true,
|
||||||
sender = src,
|
sender = src,
|
||||||
subject = subject,
|
subject = subject,
|
||||||
body = body,
|
body = body,
|
||||||
time = os.time(),
|
time = os.time(),
|
||||||
})
|
})
|
||||||
|
mail.setMessages(dst, messages)
|
||||||
|
|
||||||
for _, player in ipairs(minetest.get_connected_players()) do
|
for _, player in ipairs(minetest.get_connected_players()) do
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
|
67
gui.lua
67
gui.lua
@ -40,10 +40,10 @@ end
|
|||||||
|
|
||||||
function mail.show_inbox(name)
|
function mail.show_inbox(name)
|
||||||
local formspec = { mail.inbox_formspec }
|
local formspec = { mail.inbox_formspec }
|
||||||
mail.messages[name] = mail.messages[name] or {}
|
local messages = mail.getMessages(name)
|
||||||
|
|
||||||
if mail.messages[name][1] then
|
if messages[1] then
|
||||||
for idx, message in ipairs(mail.messages[name]) do
|
for idx, message in ipairs(messages) do
|
||||||
if message.unread then
|
if message.unread then
|
||||||
formspec[#formspec + 1] = ",#FFD700"
|
formspec[#formspec + 1] = ",#FFD700"
|
||||||
else
|
else
|
||||||
@ -76,7 +76,8 @@ function mail.show_inbox(name)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function mail.show_message(name, msgnumber)
|
function mail.show_message(name, msgnumber)
|
||||||
local message = mail.messages[name][msgnumber]
|
local messages = mail.getMessages(name)
|
||||||
|
local message = messages[msgnumber]
|
||||||
local formspec = [[
|
local formspec = [[
|
||||||
size[8,7.2]
|
size[8,7.2]
|
||||||
button[7,0;1,0.5;back;X]
|
button[7,0;1,0.5;back;X]
|
||||||
@ -124,78 +125,92 @@ function mail.handle_receivefields(player, formname, fields)
|
|||||||
minetest.after(0.5, function()
|
minetest.after(0.5, function()
|
||||||
mail.show_inbox(player:get_player_name())
|
mail.show_inbox(player:get_player_name())
|
||||||
end)
|
end)
|
||||||
|
|
||||||
elseif formname == "mail:inbox" then
|
elseif formname == "mail:inbox" then
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
|
local messages = mail.getMessages(name)
|
||||||
|
|
||||||
if fields.messages then
|
if fields.messages then
|
||||||
local evt = minetest.explode_table_event(fields.messages)
|
local evt = minetest.explode_table_event(fields.messages)
|
||||||
selected_message_idxs[name] = evt.row - 1
|
selected_message_idxs[name] = evt.row - 1
|
||||||
if evt.type == "DCL" and mail.messages[name][selected_message_idxs[name]] then
|
if evt.type == "DCL" and messages[selected_message_idxs[name]] then
|
||||||
mail.messages[name][selected_message_idxs[name]].unread = false
|
messages[selected_message_idxs[name]].unread = false
|
||||||
mail.show_message(name, selected_message_idxs[name])
|
mail.show_message(name, selected_message_idxs[name])
|
||||||
end
|
end
|
||||||
|
mail.setMessages(name, messages)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
if fields.read then
|
if fields.read then
|
||||||
if mail.messages[name][selected_message_idxs[name]] then
|
if messages[selected_message_idxs[name]] then
|
||||||
mail.messages[name][selected_message_idxs[name]].unread = false
|
messages[selected_message_idxs[name]].unread = false
|
||||||
mail.show_message(name, selected_message_idxs[name])
|
mail.show_message(name, selected_message_idxs[name])
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif fields.delete then
|
elseif fields.delete then
|
||||||
if mail.messages[name][selected_message_idxs[name]] then
|
if messages[[selected_message_idxs[name]] then
|
||||||
table.remove(mail.messages[name], selected_message_idxs[name])
|
table.remove(messages, selected_message_idxs[name])
|
||||||
end
|
end
|
||||||
|
|
||||||
mail.show_inbox(name)
|
mail.show_inbox(name)
|
||||||
mail.save()
|
elseif fields.reply and messages[selected_message_idxs[name]] then
|
||||||
elseif fields.reply and mail.messages[name][selected_message_idxs[name]] then
|
local message = messages[selected_message_idxs[name]]
|
||||||
local message = mail.messages[name][selected_message_idxs[name]]
|
|
||||||
local replyfooter = "Type your reply here.\n\n--Original message follows--\n" ..message.body
|
local replyfooter = "Type your reply here.\n\n--Original message follows--\n" ..message.body
|
||||||
mail.show_compose(name, message.sender, "Re: "..message.subject,replyfooter)
|
mail.show_compose(name, message.sender, "Re: "..message.subject,replyfooter)
|
||||||
elseif fields.forward and mail.messages[name][selected_message_idxs[name]] then
|
|
||||||
local message = mail.messages[name][selected_message_idxs[name]]
|
elseif fields.forward and messages[selected_message_idxs[name]] then
|
||||||
|
local message = messages[selected_message_idxs[name]]
|
||||||
local fwfooter = "Type your message here.\n\n--Original message follows--\n" ..message.body
|
local fwfooter = "Type your message here.\n\n--Original message follows--\n" ..message.body
|
||||||
mail.show_compose(name, "", "Fw: "..message.subject, fwfooter)
|
mail.show_compose(name, "", "Fw: "..message.subject, fwfooter)
|
||||||
|
|
||||||
elseif fields.markread then
|
elseif fields.markread then
|
||||||
if mail.messages[name][selected_message_idxs[name]] then
|
if messages[selected_message_idxs[name]] then
|
||||||
mail.messages[name][selected_message_idxs[name]].unread = false
|
messages[selected_message_idxs[name]].unread = false
|
||||||
end
|
end
|
||||||
mail.show_inbox(name)
|
mail.show_inbox(name)
|
||||||
mail.save()
|
|
||||||
elseif fields.markunread then
|
elseif fields.markunread then
|
||||||
if mail.messages[name][selected_message_idxs[name]] then
|
if messages[selected_message_idxs[name]] then
|
||||||
mail.messages[name][selected_message_idxs[name]].unread = true
|
messages[selected_message_idxs[name]].unread = true
|
||||||
end
|
end
|
||||||
mail.show_inbox(name)
|
mail.show_inbox(name)
|
||||||
mail.save()
|
|
||||||
elseif fields.new then
|
elseif fields.new then
|
||||||
mail.show_compose(name,"","","Type your message here.")
|
mail.show_compose(name,"","","Type your message here.")
|
||||||
|
|
||||||
elseif fields.quit then
|
elseif fields.quit then
|
||||||
if minetest.get_modpath("unified_inventory") then
|
if minetest.get_modpath("unified_inventory") then
|
||||||
unified_inventory.set_inventory_formspec(player, "craft")
|
unified_inventory.set_inventory_formspec(player, "craft")
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif fields.about then
|
elseif fields.about then
|
||||||
mail.show_about(name)
|
mail.show_about(name)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
mail.setMessages(name, messages)
|
||||||
return true
|
return true
|
||||||
elseif formname == "mail:message" then
|
elseif formname == "mail:message" then
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
|
local messages = mail.getMessages(name)
|
||||||
|
|
||||||
if fields.back then
|
if fields.back then
|
||||||
mail.show_inbox(name)
|
mail.show_inbox(name)
|
||||||
elseif fields.reply then
|
elseif fields.reply then
|
||||||
local message = mail.messages[name][selected_message_idxs[name]]
|
local message = messages[selected_message_idxs[name]]
|
||||||
local replyfooter = "Type your reply here.\n\n--Original message follows--\n" ..message.body
|
local replyfooter = "Type your reply here.\n\n--Original message follows--\n" ..message.body
|
||||||
mail.show_compose(name, message.sender, "Re: "..message.subject, replyfooter)
|
mail.show_compose(name, message.sender, "Re: "..message.subject, replyfooter)
|
||||||
elseif fields.forward then
|
elseif fields.forward then
|
||||||
local message = mail.messages[name][selected_message_idxs[name]]
|
local message = messages[selected_message_idxs[name]]
|
||||||
local fwfooter = "Type your message here.\n\n--Original message follows--\n" ..message.body
|
local fwfooter = "Type your message here.\n\n--Original message follows--\n" ..message.body
|
||||||
mail.show_compose(name, "", "Fw: "..message.subject, fwfooter)
|
mail.show_compose(name, "", "Fw: "..message.subject, fwfooter)
|
||||||
elseif fields.delete then
|
elseif fields.delete then
|
||||||
if mail.messages[name][selected_message_idxs[name]] then
|
if messages[selected_message_idxs[name]] then
|
||||||
table.remove(mail.messages[name],selected_message_idxs[name])
|
table.remove(messages,selected_message_idxs[name])
|
||||||
end
|
end
|
||||||
mail.show_inbox(name)
|
mail.show_inbox(name)
|
||||||
mail.save()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
mail.setMessages(name, messages)
|
||||||
return true
|
return true
|
||||||
elseif formname == "mail:compose" then
|
elseif formname == "mail:compose" then
|
||||||
if fields.send then
|
if fields.send then
|
||||||
|
13
init.lua
13
init.lua
@ -1,9 +1,12 @@
|
|||||||
mail = {}
|
mail = {
|
||||||
|
maildir = minetest.get_worldpath().."/mails"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
local MP = minetest.get_modpath(minetest.get_current_modname())
|
||||||
dofile(MP .. "/chatcommands.lua")
|
dofile(MP .. "/chatcommands.lua")
|
||||||
dofile(MP .. "/persistence.lua")
|
dofile(MP .. "/migrate.lua")
|
||||||
|
dofile(MP .. "/storage.lua")
|
||||||
dofile(MP .. "/api.lua")
|
dofile(MP .. "/api.lua")
|
||||||
dofile(MP .. "/gui.lua")
|
dofile(MP .. "/gui.lua")
|
||||||
|
|
||||||
@ -29,7 +32,5 @@ if http then
|
|||||||
mail.webmail_init(http, webmail_url, webmail_key)
|
mail.webmail_init(http, webmail_url, webmail_key)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- migrate storage
|
||||||
|
mail.migrate()
|
||||||
|
|
||||||
mail.load()
|
|
||||||
|
24
migrate.lua
Normal file
24
migrate.lua
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
-- migrate from mail.db to player-file-based mailbox
|
||||||
|
|
||||||
|
mail.migrate = function()
|
||||||
|
|
||||||
|
local file = io.open(minetest.get_worldpath().."/mail.db", "r")
|
||||||
|
if file then
|
||||||
|
print("[mail] migrating to new per-player storage")
|
||||||
|
minetest.mkdir(mail.maildir)
|
||||||
|
|
||||||
|
local data = file:read("*a")
|
||||||
|
local oldmails = minetest.deserialize(data)
|
||||||
|
file:close()
|
||||||
|
|
||||||
|
for name, oldmessages in pairs(oldmails)
|
||||||
|
mail.setMessages(name, oldmessages)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- rename file
|
||||||
|
print("[mail] migration done, renaming old mail.db")
|
||||||
|
os.rename(minetest.get_worldpath().."/mail.db", minetest.get_worldpath().."/mail.db.old")
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
11
onjoin.lua
11
onjoin.lua
@ -1,13 +1,14 @@
|
|||||||
minetest.register_on_joinplayer(function(player)
|
minetest.register_on_joinplayer(function(player)
|
||||||
minetest.after(2, function(name)
|
minetest.after(2, function(name)
|
||||||
|
local messages = mail.getMessages(name)
|
||||||
local unreadflag = false
|
local unreadflag = false
|
||||||
if mail.messages[name] then
|
|
||||||
for _, message in ipairs(mail.messages[name]) do
|
for _, message in ipairs(messages) do
|
||||||
if message.unread then
|
if message.unread then
|
||||||
unreadflag = true
|
unreadflag = true
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if unreadflag then
|
if unreadflag then
|
||||||
minetest.show_formspec(name, "mail:unreadnag",
|
minetest.show_formspec(name, "mail:unreadnag",
|
||||||
"size[3,2]" ..
|
"size[3,2]" ..
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
|
|
||||||
function mail.load()
|
|
||||||
local file = io.open(minetest.get_worldpath().."/mail.db", "r")
|
|
||||||
if file then
|
|
||||||
local data = file:read("*a")
|
|
||||||
mail.messages = minetest.deserialize(data)
|
|
||||||
file:close()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function mail.save()
|
|
||||||
local file = io.open(minetest.get_worldpath().."/mail.db","w")
|
|
||||||
if file and file:write(minetest.serialize(mail.messages)) and file:close() then
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
minetest.log("error","[mail] Save failed - messages may be lost!")
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- save periodically
|
|
||||||
local timer = 0
|
|
||||||
minetest.register_globalstep(function(dtime)
|
|
||||||
timer = timer + dtime
|
|
||||||
if timer < 30 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
timer = 0
|
|
||||||
mail.save()
|
|
||||||
end)
|
|
31
storage.lua
Normal file
31
storage.lua
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
-- TODO: maybe local cache?
|
||||||
|
|
||||||
|
function getMailFile(playername)
|
||||||
|
return mail.maildir .. "/" .. playername .. ".json"
|
||||||
|
end
|
||||||
|
|
||||||
|
mail.getMessages = function(playername)
|
||||||
|
local file = io.open(getMailFile(playername),"w", "r")
|
||||||
|
local messages = {}
|
||||||
|
if file then
|
||||||
|
local json = file:read("*a")
|
||||||
|
messages = minetest.parse_json(json) or {}
|
||||||
|
file:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
return messages
|
||||||
|
end
|
||||||
|
|
||||||
|
mail.setMessages = function(playername, messages)
|
||||||
|
local file = io.open(getMailFile(playername),"w")
|
||||||
|
local json = minetest.write_json(messages)
|
||||||
|
if file and file:write(json) and file:close() then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
minetest.log("error","[mail] Save failed - messages may be lost!")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
21
webmail.lua
21
webmail.lua
@ -50,32 +50,39 @@ end
|
|||||||
|
|
||||||
-- get player messages request from webmail
|
-- get player messages request from webmail
|
||||||
local function get_player_messages_handler(playername)
|
local function get_player_messages_handler(playername)
|
||||||
|
local messages = mail.getMessages(playername)
|
||||||
channel.send({
|
channel.send({
|
||||||
type = "player-messages",
|
type = "player-messages",
|
||||||
playername = playername,
|
playername = playername,
|
||||||
data = mail.messages[playername]
|
data = messages
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
-- remove mail
|
-- remove mail
|
||||||
local function delete_mail_handler(playername, index)
|
local function delete_mail_handler(playername, index)
|
||||||
if mail.messages[playername] and mail.messages[playername][index] then
|
local messages = mail.getMessages(playername)
|
||||||
table.remove(mail.messages[playername], index)
|
if messages[index] then
|
||||||
|
table.remove(messages, index)
|
||||||
end
|
end
|
||||||
|
mail.setMessages(playername, messages)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- mark mail as read
|
-- mark mail as read
|
||||||
local function mark_mail_read_handler(playername, index)
|
local function mark_mail_read_handler(playername, index)
|
||||||
if mail.messages[playername] and mail.messages[playername][index] then
|
local messages = mail.getMessages(playername)
|
||||||
mail.messages[playername][index].unread = false
|
if messages[index] then
|
||||||
|
messages[index].unread = false
|
||||||
end
|
end
|
||||||
|
mail.setMessages(playername, messages)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- mark mail as unread
|
-- mark mail as unread
|
||||||
local function mark_mail_unread_handler(playername, index)
|
local function mark_mail_unread_handler(playername, index)
|
||||||
if mail.messages[playername] and mail.messages[playername][index] then
|
local messages = mail.getMessages(playername)
|
||||||
mail.messages[playername][index].unread = true
|
if messages[index] then
|
||||||
|
messages[index].unread = true
|
||||||
end
|
end
|
||||||
|
mail.setMessages(playername, messages)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mail.webmail_send_hook(src,dst,subject,body)
|
function mail.webmail_send_hook(src,dst,subject,body)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user