Attached. This one does standard work on netsync events but uses a file "notify" that you should put next to read-permissions and write-permissions. The semantics and format of the file are exactly the same as read-permissions (except that you want a list of email addresses to come out rather than a bool): pattern, allow, deny and continue all work as you'd expect in a top-to-bottom file way.
Currently it calls /usr/bin/mail which might mean you're out of luck on Windows. It sets the From header to be the value of the author cert and the Sender can be set to anything you like. Seems to work for me. It would be nice if this could get into contrib/ Note that this hasn't been really hard tested in complex interplays with allow and deny. I'm pretty sure that the algorithm is correct, but further testing is always welcome! Currently it doesn't do diffs, which it really should, but I refuse to shell out to another program in order to call mtn! mtn automate commands that do not modify the database should be available from hooks in lua, but that's in a different thread... Cheers, Matthew -- Matthew Sackman http://www.wellquite.org/
-- Create a file "notify" next to "read-permissions" and ensure -- its contents are in the same format as "read-permissions", -- except that the values for allow and deny must be real email -- addresses. -- -- Requires a "mail" executable -- -- Copyright (c) 2007, Matthew Sackman (matthew at wellquite dot org) -- LShift Ltd (http://www.lshift.net) -- Thomas Keller <[EMAIL PROTECTED]> -- Whoever wrote the function "get_netsync_read_permitted" -- License: GPLv2 or later _outfile = "/tmp/processor-out" _errfile = "/tmp/processor-err" _sender = "[EMAIL PROTECTED]" function get_notify_recipients(branch) local emailfile = io.open(get_confdir() .. "/notify", "r") if (emailfile == nil) then return nil end local dat = emailfile:read("*a") io.close(emailfile) local res = parse_basic_io(dat) if res == nil then io.stderr:write("file notify cannot be parsed\n") return nil end local results = {} local denied = {} local matches = false local cont = false for i, item in pairs(res) do -- legal names: pattern, allow, deny, continue if item.name == "pattern" then if matches and not cont then return table.toarray(results) end matches = false cont = false for j, val in pairs(item.values) do if globish_match(val, branch) then matches = true end end elseif item.name == "allow" then if matches then for j, val in pairs(item.values) do if nil == denied[val] then results[val] = val end end end elseif item.name == "deny" then if matches then for j, val in pairs(item.values) do denied[val] = val end end elseif item.name == "continue" then if matches then cont = true for j, val in pairs(item.values) do if val == "false" or val == "no" then cont = false end end end elseif item.name ~= "comment" then io.stderr:write("unknown symbol in notify: " .. item.name .. "\n") end end return table.toarray(results) end function table.toarray(t) local t1 = {} for j, val in pairs(t) do table.insert(t1, val) end return t1 end _emails_to_send = {} function note_netsync_start (session_id, my_role, sync_type, remote_host, remote_keyname, includes, excludes) _emails_to_send[session_id] = {} end function note_netsync_revision_received (new_id, revision, certs, session_id) if _emails_to_send[session_id] == nil then -- no session present return end local rev_data = {["certs"] = {}, ["revision"] = new_id, ["manifest"] = revision} for _,cert in ipairs(certs) do if cert["name"] == "branch" then rev_data["recipients"] = get_notify_recipients(cert["value"]) end if cert["name"] ~= nil then if nil == rev_data["certs"][cert["name"]] then rev_data["certs"][cert["name"]] = {} end table.insert(rev_data["certs"][cert["name"]], cert["value"]) end end _emails_to_send[session_id][new_id] = rev_data end function note_netsync_end (session_id, status, bytes_in, bytes_out, certs_in, certs_out, revs_in, revs_out, keys_in, keys_out) if _emails_to_send[session_id] == nil then -- no session present return end if status ~= 200 then -- some error occured, no further processing takes place return end if _emails_to_send[session_id] == "" then -- we got no interesting revisions return end for rev_id,rev_data in pairs(_emails_to_send[session_id]) do if # (rev_data["recipients"]) > 0 then file,filename = temp_file("notify") file:write(summarize_certs(rev_data)) file:close() local subject = make_subject_line(rev_data) local from_header = "From: " .. rev_data["certs"]["author"][1] for j,addr in pairs(rev_data["recipients"]) do spawn_redirected(filename, _outfile, _errfile, "/usr/bin/mail", "-e", "-a", from_header, "-a", "Sender: " .. _sender, "-s", subject, addr) end os.remove(filename) end end _emails_to_send[session_id] = nil end function summarize_certs(t) local str = "revision: " .. t["revision"] .. "\n" local changelog for name,values in pairs(t["certs"]) do local formatted_value = "" for j,val in pairs(values) do formatted_value = formatted_value .. name .. ":" if string.match(val, "\n") then formatted_value = formatted_value .. "\n" else formatted_value = formatted_value .. (string.rep(" ", 20 - (# name))) end formatted_value = formatted_value .. val .. "\n" end if name == "changelog" then changelog = formatted_value else str = str .. formatted_value end end if nil ~= changelog then str = str .. changelog end return (str .. "manifest:\n" .. t["manifest"]) end function make_subject_line(t) local str = "" for j,val in pairs(t["certs"]["branch"]) do str = str .. val if j < # t["certs"]["branch"] then str = str .. ", " end end return str .. ": " .. t["revision"] end function table.print(T) local done = {} local function tprint_r(T, prefix) for k,v in pairs(T) do print(prefix..tostring(k),'=',tostring(v)) if type(v) == 'table' then if not done[v] then done[v] = true tprint_r(v, prefix.." ") end end end end done[T] = true tprint_r(T, "") end
_______________________________________________ Monotone-devel mailing list [email protected] http://lists.nongnu.org/mailman/listinfo/monotone-devel
