On Sun, Sep 30, 2007 at 05:07:06PM +0100, Matthew Sackman wrote:
> Right, well, due to the continuously locked mtn db for servers, it makes
> notification scripts a bit more complex. The patch attached does roughly
> the following:

The patch attached does all of the above, but it also now deals with the
case of revisions which have no parent. (err, it's a completely new
patch, not an incremental patch, so ignore my previous patch in this
thread.)

And as discussed on IRC, this shouldn't really be called "standalone"
any more, as it has both the lua and sh part.

Could someone have a look over this and commit it please?

Many thanks,

Matthew
#
# old_revision [33513953412998e03c1027d4e802fca6da9e9d1c]
#
# add_file "contrib/monotone-mail-notify-standalone.sh"
#  content [7de62a542b7b20d9cf2b8d2bc14c685bd34efdb8]
# 
# patch "contrib/monotone-mail-notify-standalone.lua"
#  from [89e0cd79a1a44761c15a9f3556e6b62313c6e605]
#    to [b451b8b6da1a0f92dcb9d372fe1935972f9eafaa]
#
============================================================
--- contrib/monotone-mail-notify-standalone.sh  
7de62a542b7b20d9cf2b8d2bc14c685bd34efdb8
+++ contrib/monotone-mail-notify-standalone.sh  
7de62a542b7b20d9cf2b8d2bc14c685bd34efdb8
@@ -0,0 +1,121 @@
+#! /bin/sh
+
+# 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. Install the corresponding .lua file in monotone.
+#
+# Call this script from cron or similar to process files
+# generated by the .lua file.
+#
+# Copyright (c) 2007, Matthew Sackman (matthew at wellquite dot org)
+#                     LShift Ltd (http://www.lshift.net)
+# License: GPLv2 or later
+
+DB="/path/to/a/private/unused/db.mtn"
+MTN="/usr/bin/mtn"
+SERVER="localhost"
+HIGHLIGHT="/usr/bin/source-highlight"
+MIMECONSTRUCT="/usr/bin/mime-construct"
+BASE="/tmp/notify"
+
+function processFile() {
+    local fileBase=$1
+
+    local hdr="$fileBase.hdr.txt"
+    local rev="$fileBase.rev.txt"
+    if [ ! -f $hdr ]
+    then
+       echo "Specified header file '$hdr' does not exist"
+       exit 1
+    fi
+
+    if [ ! -f $rev ]
+    then
+       echo "Specified revision file '$hdr' does not exist"
+       exit 1
+    fi
+
+    local revision=$(cat $rev | grep '^revision:' | sed -e 's/^revision:[ 
]\+//')
+
+    local parts=()
+    local files=()
+    let fIdx=0
+    let pIdx=0
+    local parents=$($MTN --reallyquiet -d $DB automate parents $revision)
+    if [ "x" == "x$parents" ]
+    then
+       local plainDiff="$revision.noparent.diff"
+       local htmlDiff="$revision.noparent.html"
+       local partFile="$revision.noparent.part"
+       files[0]=$plainDiff
+       files[1]=$htmlDiff
+       parts[0]=$partFile
+       $MTN --reallyquiet -d $DB log --diffs --brief --no-graph --from 
$revision --to $revision > $plainDiff
+       cat $plainDiff | $HIGHLIGHT -s diff -f html > $htmlDiff
+       $MIMECONSTRUCT --subpart --multipart multipart/alternative \
+           --type text/plain --part-header "Content-Type: text/plain" 
--encoding quoted-printable --file $plainDiff \
+           --type text/html --encoding quoted-printable --file $htmlDiff \
+           > $partFile
+    else
+       for p in $parents
+       do
+         local plainDiff="$revision.$p.diff"
+         local htmlDiff="$revision.$p.html"
+         local partFile="$revision.$p.part"
+         files[$fIdx]=$plainDiff
+         files[$fIdx+1]=$htmlDiff
+         let fIdx+=2
+         $MTN --reallyquiet -d $DB diff -r $p -r $revision > $plainDiff
+         cat $plainDiff | $HIGHLIGHT -s diff -f html > $htmlDiff
+         $MIMECONSTRUCT --subpart --multipart multipart/alternative \
+             --type text/plain --part-header "Content-Type: text/plain" 
--encoding quoted-printable --file $plainDiff \
+             --type text/html --encoding quoted-printable --file $htmlDiff \
+             > $partFile
+         parts[$pIdx]=$partFile
+         let pIdx+=1
+       done
+    fi
+
+    local margs=""
+    for p in [EMAIL PROTECTED]
+    do
+      margs="$margs --subpart-file $p"
+    done
+
+    local hdrargs=$(cat $hdr)
+    $MIMECONSTRUCT --embedded-to --header "$hdrargs" --multipart 
multipart/mixed \
+       --type text/plain --part-header "Content-Type: text/plain" --encoding 
quoted-printable --file $rev \
+       $margs
+
+    for p in [EMAIL PROTECTED]
+    do
+      rm $p
+    done
+
+    for f in [EMAIL PROTECTED]
+    do
+      rm $f
+    done
+
+    rm $hdr
+    rm $rev
+}
+
+if [ "x" == "x$(ls $BASE)" ]
+then
+    exit 0
+fi
+
+$MTN --reallyquiet -d $DB pull $SERVER '*'
+
+cwd=$(pwd)
+cd $BASE
+
+for f in $(ls $BASE | grep '.hdr.txt$')
+do
+  name=$(basename "$f" '.hdr.txt')
+  processFile "$BASE/$name"
+done
+
+cd "$cwd"
============================================================
--- contrib/monotone-mail-notify-standalone.lua 
89e0cd79a1a44761c15a9f3556e6b62313c6e605
+++ contrib/monotone-mail-notify-standalone.lua 
b451b8b6da1a0f92dcb9d372fe1935972f9eafaa
@@ -1,9 +1,10 @@
 -- 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
+-- This will splat out files in _base. Use the .sh file from
+-- cron to process those files
 --
 -- Copyright (c) 2007, Matthew Sackman (matthew at wellquite dot org)
 --                     LShift Ltd (http://www.lshift.net)
@@ -11,9 +12,8 @@
 --                     Whoever wrote the function "get_netsync_read_permitted"
 -- License: GPLv2 or later
 
-_outfile = "/tmp/processor-out"
-_errfile = "/tmp/processor-err"
 _from = "[EMAIL PROTECTED]"
+_base = "/tmp/notify/"
 
 function get_notify_recipients(branch)
    local emailfile = io.open(get_confdir() .. "/notify", "r")
@@ -85,53 +85,76 @@ function note_netsync_revision_received 
         if cert["name"] == "branch" then
            rev_data["recipients"] = get_notify_recipients(cert["value"])
         end
-       if cert["name"] ~= nil then
+        if cert["name"] ~= nil then
            if nil == rev_data["certs"][cert["name"]] then
-             rev_data["certs"][cert["name"]] = {}
-          end
+              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
+do
+   local saved_note_netsync_end = note_netsync_end
 
-    if status ~= 200 then
-        -- some error occured, no further processing takes place
-        return
-    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 saved_note_netsync_end then
+         saved_note_netsync_end(session_id, status,
+                                bytes_in, bytes_out,
+                                certs_in, certs_out,
+                                revs_in, revs_out,
+                                keys_in, keys_out,
+                                unpack(arg))
+      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 reply_to = "Reply-To: "
-         for j,auth in pairs(rev_data["certs"]["author"]) do
-            reply_to = reply_to .. auth
-            if j < # (rev_data["certs"]["author"]) then reply_to = reply_to .. 
", " end
-         end
 
-         for j,addr in pairs(rev_data["recipients"]) do
-            spawn_redirected(filename, _outfile, _errfile, "/usr/bin/mail", 
"-e", "-a", reply_to, "-a", "From: " .. _from, "-s", subject, addr)
-         end
+      if _emails_to_send[session_id] == nil then
+         -- no session present
+         return
+      end
 
-         os.remove(filename)
-       end
-    end
-     
-    _emails_to_send[session_id] = nil
+      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
+            local subject = make_subject_line(rev_data)
+            local reply_to = ""
+            for j,auth in pairs(rev_data["certs"]["author"]) do
+               reply_to = reply_to .. auth
+               if j < # (rev_data["certs"]["author"]) then reply_to = reply_to 
.. ", " end
+            end
+
+            local outputFileRev = io.open(_base .. rev_data["revision"] .. 
os.time() .. ".rev.txt", "w+")
+            local outputFileHdr = io.open(_base .. rev_data["revision"] .. 
os.time() .. ".hdr.txt", "w+")
+
+            local to = ""
+            for j,addr in pairs(rev_data["recipients"]) do
+               to = to .. addr
+               if j < # (rev_data["recipients"]) then to = to .. ", " end
+            end
+
+            outputFileHdr:write("BCC: " .. to .. "\n")
+            outputFileHdr:write("From: " .. _from .. "\n")
+            outputFileHdr:write("Subject: " .. subject .. "\n")
+            outputFileHdr:write("Reply-To: " .. reply_to .. "\n")
+            outputFileHdr:close()
+
+            outputFileRev:write(summarize_certs(rev_data))
+            outputFileRev:close()
+         end
+      end
+
+      _emails_to_send[session_id] = nil
+   end
 end
 
 function summarize_certs(t)
@@ -140,10 +163,10 @@ function summarize_certs(t)
    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 .. 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
_______________________________________________
Monotone-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/monotone-devel

Reply via email to