| rev | line source | 
| bsw@1248 | 1 InitiativeForNotification = mondelefant.new_class() | 
| bsw@1248 | 2 InitiativeForNotification.table = 'initiative_for_notification' | 
| bsw@1248 | 3 | 
| bsw@1248 | 4 InitiativeForNotification:add_reference{ | 
| bsw@1248 | 5   mode          = 'm1', | 
| bsw@1248 | 6   to            = "Initiative", | 
| bsw@1248 | 7   this_key      = 'initiative_id', | 
| bsw@1248 | 8   that_key      = 'id', | 
| bsw@1248 | 9   ref           = 'initiative', | 
| bsw@1248 | 10 } | 
| bsw@1248 | 11 | 
| bsw@1248 | 12 | 
| bsw@1248 | 13 function InitiativeForNotification:notify_member_id(member_id) | 
| bsw@1248 | 14 | 
| bsw@1248 | 15   db:query("BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ") | 
| bsw@1248 | 16 | 
| bsw@1248 | 17   local member = Member:by_id(member_id) | 
| bsw@1252 | 18 | 
| bsw@1248 | 19   locale.set{ lang = member.lang or config.default_lang } | 
| bsw@1248 | 20 | 
| bsw@1248 | 21   local selector = db:new_selector() | 
| bsw@1248 | 22     :add_field("*") | 
| bsw@1248 | 23     :from({ "get_initiatives_for_notification(?)", member_id }, "initiative_for_notification") | 
| bsw@1413 | 24     :left_join("initiative", nil, "initiative.id = initiative_for_notification.initiative_id") | 
| bsw@1413 | 25     :left_join("issue", nil, "issue.id = initiative.issue_id") | 
| bsw@1248 | 26     :join("member", nil, "member.id = initiative_for_notification.recipient_id") | 
| bsw@1248 | 27     :add_order_by("md5(initiative_for_notification.recipient_id || '-' || member.notification_counter || '-' || issue.area_id)") | 
| bsw@1248 | 28     :add_order_by("md5(initiative_for_notification.recipient_id || '-' || member.notification_counter || '-' || issue.id)") | 
| bsw@1252 | 29 | 
| bsw@1248 | 30   selector._class = self | 
| bsw@1248 | 31 | 
| bsw@1248 | 32   local initiatives_for_notification = selector:exec() | 
| bsw@1248 | 33 | 
| bsw@1252 | 34   db:query("COMMIT") | 
| bsw@1252 | 35 | 
| bsw@1252 | 36   if not member.notify_email then | 
| bsw@1248 | 37     return | 
| bsw@1248 | 38   end | 
| bsw@1248 | 39 | 
| bsw@1278 | 40   if #initiatives_for_notification < 1 then | 
| bsw@1252 | 41     return | 
| bsw@1252 | 42   end | 
| bsw@1252 | 43 | 
| bsw@1252 | 44   io.stderr:write("Sending digest #" .. member.notification_counter .. " to " .. member.notify_email .. "\n") | 
| bsw@1252 | 45 | 
| bsw@1248 | 46   local initiatives = initiatives_for_notification:load("initiative") | 
| bsw@1248 | 47   local issues = initiatives:load("issue") | 
| bsw@1248 | 48   issues:load("area") | 
| bsw@1248 | 49   issues:load("policy") | 
| bsw@1248 | 50 | 
| bsw@1248 | 51   local last_area_id | 
| bsw@1248 | 52   local last_issue_id | 
| bsw@1248 | 53 | 
| bsw@1248 | 54   local draft_count = 0 | 
| bsw@1248 | 55   local suggestion_count = 0 | 
| bsw@1248 | 56 | 
| bsw@1252 | 57   local draft_initiative | 
| bsw@1252 | 58   local suggestion_initiative | 
| bsw@1252 | 59 | 
| bsw@1248 | 60   local ms = {} | 
| bsw@1248 | 61 | 
| bsw@1248 | 62   for i, entry in ipairs(initiatives_for_notification) do | 
| bsw@1248 | 63     local initiative = entry.initiative | 
| bsw@1248 | 64     local issue = initiative.issue | 
| bsw@1248 | 65     local area = issue.area | 
| bsw@1248 | 66     local policy = issue.policy | 
| bsw@1248 | 67 | 
| bsw@1248 | 68     local m = {} | 
| bsw@1248 | 69     if last_area_id ~= area.id then | 
| bsw@1248 | 70       m[#m+1] = "*** " .. area.name .. " ***" | 
| bsw@1248 | 71       m[#m+1] = "" | 
| bsw@1248 | 72       last_area_id = area.id | 
| bsw@1248 | 73     end | 
| bsw@1248 | 74     if last_issue_id ~= issue.id then | 
| bsw@1248 | 75       local state_time_text | 
| bsw@1248 | 76       if string.sub(issue.state_time_left, 1, 1) == "-" then | 
| bsw@1248 | 77         state_time_text = _"Phase ends soon" | 
| bsw@1248 | 78       else | 
| bsw@1305 | 79         state_time_text = format.interval_text(issue.state_time_left, { mode = "time_left" }) | 
| bsw@1248 | 80       end | 
| bsw@1248 | 81       m[#m+1] = "---" | 
| bsw@1248 | 82       m[#m+1] = policy.name .. " #" .. issue.id .. " - " .. issue.state_name .. " - " .. state_time_text | 
| bsw@1248 | 83       m[#m+1] = "" | 
| bsw@1248 | 84       last_issue_id = issue.id | 
| bsw@1248 | 85     end | 
| bsw@1248 | 86     m[#m+1] = initiative.display_name | 
| bsw@1248 | 87     local source | 
| bsw@1248 | 88     if entry.supported then | 
| bsw@1248 | 89       source = _"has my support" | 
| bsw@1248 | 90       if entry.new_draft then | 
| bsw@1252 | 91         source = source .. ", " .. _"draft updated" | 
| bsw@1248 | 92         draft_count = draft_count + 1 | 
| bsw@1252 | 93         draft_initiative = initiative | 
| bsw@1248 | 94       end | 
| bsw@1248 | 95       if entry.new_suggestion_count then | 
| bsw@1248 | 96         if entry.new_suggestion_count == 1 then | 
| bsw@1252 | 97           source = source .. ", " .. _"new suggestion added" | 
| bsw@1248 | 98         elseif entry.new_suggestion_count > 1 then | 
| bsw@1252 | 99           source = source .. ", " .. _("#{count} suggestions added", { count = entry.new_suggestion_count }) | 
| bsw@1248 | 100         end | 
| bsw@1248 | 101         suggestion_count = suggestion_count + entry.new_suggestion_count | 
| bsw@1252 | 102         if suggestion_initiative and suggestion_initiative.id ~= initiative.id then | 
| bsw@1252 | 103           suggestion_initiative = false | 
| bsw@1252 | 104         elseif suggestion_initiative ~= false then | 
| bsw@1252 | 105           suggestion_initiative = initiative | 
| bsw@1252 | 106         end | 
| bsw@1248 | 107       end | 
| bsw@1248 | 108     elseif entry.featured then | 
| bsw@1248 | 109       source = _"featured" | 
| bsw@1248 | 110     end | 
| bsw@1248 | 111     if entry.leading then | 
| bsw@1248 | 112       source = source and source .. ", " or "" | 
| bsw@1305 | 113       source = source .. _"currently leading" | 
| bsw@1248 | 114     end | 
| bsw@1248 | 115     m[#m+1] = "(" .. source .. ")" | 
| bsw@1248 | 116     m[#m+1] = "" | 
| bsw@1248 | 117     if not initiatives_for_notification[i+1] or initiatives_for_notification[i+1].issue_id ~= issue.id then | 
| bsw@1248 | 118       m[#m+1] = _("more: #{url}", { url = request.get_absolute_baseurl() .. "issue/show/" .. issue.id .. ".html" }) | 
| bsw@1248 | 119       m[#m+1] = "" | 
| bsw@1248 | 120     end | 
| bsw@1248 | 121     ms[#ms+1] = table.concat(m, "\n") | 
| bsw@1248 | 122   end | 
| bsw@1248 | 123 | 
| bsw@1248 | 124   local info = {} | 
| bsw@1248 | 125 | 
| bsw@1248 | 126   if draft_count > 0 then | 
| bsw@1248 | 127     if draft_count == 1 then | 
| bsw@1252 | 128       info[#info+1] = _"draft updated for " .. draft_initiative.display_name | 
| bsw@1248 | 129     else | 
| bsw@1248 | 130       info[#info+1] = _("drafts of #{draft_count} initiatives updated", { draft_count = draft_count }) | 
| bsw@1248 | 131     end | 
| bsw@1248 | 132   end | 
| bsw@1248 | 133 | 
| bsw@1248 | 134   if suggestion_count > 0 then | 
| bsw@1248 | 135     if suggestion_count == 1 then | 
| bsw@1252 | 136       info[#info+1] = _"new suggestion for " .. suggestion_initiative.display_name | 
| bsw@1252 | 137     elseif suggestion_initiative then | 
| bsw@1252 | 138       info[#info+1] = _("#{count} suggestions added for #{initiative}", { count = suggestion_count, suggestion_initiative.display_name }) | 
| bsw@1248 | 139     else | 
| bsw@1250 | 140       info[#info+1] = _("#{count} suggestions added", { count = suggestion_count }) | 
| bsw@1248 | 141     end | 
| bsw@1248 | 142   end | 
| bsw@1248 | 143 | 
| bsw@1248 | 144   if draft_count == 0 and suggestion_count == 0 then | 
| bsw@1248 | 145     info[#info+1] = _"featured initiatives" | 
| bsw@1248 | 146   end | 
| bsw@1248 | 147 | 
| bsw@1248 | 148   local subject = _("Digest #{id}: #{info}", { | 
| bsw@1248 | 149     id = member.notification_counter, info = table.concat(info, ", ") | 
| bsw@1248 | 150   }) | 
| bsw@1248 | 151 | 
| bsw@1248 | 152   local template = config.notification_digest_template | 
| bsw@1248 | 153 | 
| bsw@1248 | 154   local message = _(template, { | 
| bsw@1248 | 155     name = member.name, | 
| bsw@1248 | 156     digest = table.concat(ms, "\n") | 
| bsw@1248 | 157   }) | 
| bsw@1248 | 158 | 
| bsw@1248 | 159   local success = net.send_mail{ | 
| bsw@1248 | 160     envelope_from = config.mail_envelope_from, | 
| bsw@1248 | 161     from          = config.mail_from, | 
| bsw@1248 | 162     reply_to      = config.mail_reply_to, | 
| bsw@1305 | 163     to            = { name = member.name, address = member.notify_email }, | 
| bsw@1248 | 164     subject       = subject, | 
| bsw@1248 | 165     content_type  = "text/plain; charset=UTF-8", | 
| bsw@1248 | 166     content       = message | 
| bsw@1248 | 167   } | 
| bsw@1248 | 168 | 
| bsw@1248 | 169 end | 
| bsw@1248 | 170 | 
| bsw@1248 | 171 function InitiativeForNotification:notify_next_member() | 
| bsw@1248 | 172   local scheduled_notification_to_send = ScheduledNotificationToSend:get_next() | 
| bsw@1248 | 173   if not scheduled_notification_to_send then | 
| bsw@1248 | 174     return false | 
| bsw@1248 | 175   end | 
| bsw@1248 | 176   InitiativeForNotification:notify_member_id(scheduled_notification_to_send.recipient_id) | 
| bsw@1248 | 177   return true | 
| bsw@1248 | 178 end | 
| bsw@1248 | 179 |