| 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@1248
 | 
    24     :join("initiative", nil, "initiative.id = initiative_for_notification.initiative_id")
 | 
| 
bsw@1248
 | 
    25     :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@1252
 | 
    40   if not #initiatives_for_notification > 0 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@1248
 | 
    79         state_time_text = _( "#{interval} left", {
 | 
| 
bsw@1248
 | 
    80           interval = format.interval_text(issue.state_time_left)
 | 
| 
bsw@1248
 | 
    81         })
 | 
| 
bsw@1248
 | 
    82       end
 | 
| 
bsw@1248
 | 
    83       m[#m+1] = "---"
 | 
| 
bsw@1248
 | 
    84       m[#m+1] = policy.name .. " #" .. issue.id .. " - " .. issue.state_name .. " - " .. state_time_text
 | 
| 
bsw@1248
 | 
    85       m[#m+1] = ""
 | 
| 
bsw@1248
 | 
    86       last_issue_id = issue.id
 | 
| 
bsw@1248
 | 
    87     end
 | 
| 
bsw@1248
 | 
    88     m[#m+1] = initiative.display_name
 | 
| 
bsw@1248
 | 
    89     local source
 | 
| 
bsw@1248
 | 
    90     if entry.supported then
 | 
| 
bsw@1248
 | 
    91       source = _"has my support"
 | 
| 
bsw@1248
 | 
    92       if entry.new_draft then
 | 
| 
bsw@1252
 | 
    93         source = source .. ", " .. _"draft updated"
 | 
| 
bsw@1248
 | 
    94         draft_count = draft_count + 1
 | 
| 
bsw@1252
 | 
    95         draft_initiative = initiative
 | 
| 
bsw@1248
 | 
    96       end
 | 
| 
bsw@1248
 | 
    97       if entry.new_suggestion_count then
 | 
| 
bsw@1248
 | 
    98         if entry.new_suggestion_count == 1 then
 | 
| 
bsw@1252
 | 
    99           source = source .. ", " .. _"new suggestion added"
 | 
| 
bsw@1248
 | 
   100         elseif entry.new_suggestion_count > 1 then
 | 
| 
bsw@1252
 | 
   101           source = source .. ", " .. _("#{count} suggestions added", { count = entry.new_suggestion_count })
 | 
| 
bsw@1248
 | 
   102         end
 | 
| 
bsw@1248
 | 
   103         suggestion_count = suggestion_count + entry.new_suggestion_count
 | 
| 
bsw@1252
 | 
   104         if suggestion_initiative and suggestion_initiative.id ~= initiative.id then
 | 
| 
bsw@1252
 | 
   105           suggestion_initiative = false
 | 
| 
bsw@1252
 | 
   106         elseif suggestion_initiative ~= false then
 | 
| 
bsw@1252
 | 
   107           suggestion_initiative = initiative
 | 
| 
bsw@1252
 | 
   108         end
 | 
| 
bsw@1248
 | 
   109       end
 | 
| 
bsw@1248
 | 
   110     elseif entry.featured then
 | 
| 
bsw@1248
 | 
   111       source = _"featured"
 | 
| 
bsw@1248
 | 
   112     end
 | 
| 
bsw@1248
 | 
   113     if entry.leading then
 | 
| 
bsw@1248
 | 
   114       source = source and source .. ", " or ""
 | 
| 
bsw@1248
 | 
   115       source = source .. "currently leading"
 | 
| 
bsw@1248
 | 
   116     end
 | 
| 
bsw@1248
 | 
   117     m[#m+1] = "(" .. source .. ")"
 | 
| 
bsw@1248
 | 
   118     m[#m+1] = ""
 | 
| 
bsw@1248
 | 
   119     if not initiatives_for_notification[i+1] or initiatives_for_notification[i+1].issue_id ~= issue.id then
 | 
| 
bsw@1248
 | 
   120       m[#m+1] = _("more: #{url}", { url = request.get_absolute_baseurl() .. "issue/show/" .. issue.id .. ".html" })
 | 
| 
bsw@1248
 | 
   121       m[#m+1] = ""
 | 
| 
bsw@1248
 | 
   122     end
 | 
| 
bsw@1248
 | 
   123     ms[#ms+1] = table.concat(m, "\n")
 | 
| 
bsw@1248
 | 
   124   end
 | 
| 
bsw@1248
 | 
   125 
 | 
| 
bsw@1248
 | 
   126   local info = {}
 | 
| 
bsw@1248
 | 
   127     
 | 
| 
bsw@1248
 | 
   128   if draft_count > 0 then
 | 
| 
bsw@1248
 | 
   129     if draft_count == 1 then
 | 
| 
bsw@1252
 | 
   130       info[#info+1] = _"draft updated for " .. draft_initiative.display_name
 | 
| 
bsw@1248
 | 
   131     else
 | 
| 
bsw@1248
 | 
   132       info[#info+1] = _("drafts of #{draft_count} initiatives updated", { draft_count = draft_count })
 | 
| 
bsw@1248
 | 
   133     end
 | 
| 
bsw@1248
 | 
   134   end
 | 
| 
bsw@1248
 | 
   135   
 | 
| 
bsw@1248
 | 
   136   if suggestion_count > 0 then
 | 
| 
bsw@1248
 | 
   137     if suggestion_count == 1 then
 | 
| 
bsw@1252
 | 
   138       info[#info+1] = _"new suggestion for " .. suggestion_initiative.display_name
 | 
| 
bsw@1252
 | 
   139     elseif suggestion_initiative then
 | 
| 
bsw@1252
 | 
   140       info[#info+1] = _("#{count} suggestions added for #{initiative}", { count = suggestion_count, suggestion_initiative.display_name })
 | 
| 
bsw@1248
 | 
   141     else
 | 
| 
bsw@1250
 | 
   142       info[#info+1] = _("#{count} suggestions added", { count = suggestion_count })
 | 
| 
bsw@1248
 | 
   143     end
 | 
| 
bsw@1248
 | 
   144   end
 | 
| 
bsw@1248
 | 
   145   
 | 
| 
bsw@1248
 | 
   146   if draft_count == 0 and suggestion_count == 0 then
 | 
| 
bsw@1248
 | 
   147     info[#info+1] = _"featured initiatives"
 | 
| 
bsw@1248
 | 
   148   end
 | 
| 
bsw@1248
 | 
   149   
 | 
| 
bsw@1248
 | 
   150   local subject = _("Digest #{id}: #{info}", {
 | 
| 
bsw@1248
 | 
   151     id = member.notification_counter, info = table.concat(info, ", ")
 | 
| 
bsw@1248
 | 
   152   })
 | 
| 
bsw@1248
 | 
   153   
 | 
| 
bsw@1248
 | 
   154   local template = config.notification_digest_template
 | 
| 
bsw@1248
 | 
   155   
 | 
| 
bsw@1248
 | 
   156   local message = _(template, {
 | 
| 
bsw@1248
 | 
   157     name = member.name,
 | 
| 
bsw@1248
 | 
   158     digest = table.concat(ms, "\n")
 | 
| 
bsw@1248
 | 
   159   })
 | 
| 
bsw@1248
 | 
   160   
 | 
| 
bsw@1248
 | 
   161   local success = net.send_mail{
 | 
| 
bsw@1248
 | 
   162     envelope_from = config.mail_envelope_from,
 | 
| 
bsw@1248
 | 
   163     from          = config.mail_from,
 | 
| 
bsw@1248
 | 
   164     reply_to      = config.mail_reply_to,
 | 
| 
bsw@1248
 | 
   165     to            = member.notify_email,
 | 
| 
bsw@1248
 | 
   166     subject       = subject,
 | 
| 
bsw@1248
 | 
   167     content_type  = "text/plain; charset=UTF-8",
 | 
| 
bsw@1248
 | 
   168     content       = message
 | 
| 
bsw@1248
 | 
   169   }
 | 
| 
bsw@1248
 | 
   170 
 | 
| 
bsw@1248
 | 
   171 end
 | 
| 
bsw@1248
 | 
   172 
 | 
| 
bsw@1248
 | 
   173 function InitiativeForNotification:notify_next_member()
 | 
| 
bsw@1248
 | 
   174   local scheduled_notification_to_send = ScheduledNotificationToSend:get_next()
 | 
| 
bsw@1248
 | 
   175   if not scheduled_notification_to_send then
 | 
| 
bsw@1248
 | 
   176     return false
 | 
| 
bsw@1248
 | 
   177   end
 | 
| 
bsw@1248
 | 
   178   InitiativeForNotification:notify_member_id(scheduled_notification_to_send.recipient_id)
 | 
| 
bsw@1248
 | 
   179   return true
 | 
| 
bsw@1248
 | 
   180 end
 | 
| 
bsw@1248
 | 
   181 
 | 
| 
bsw@1250
 | 
   182 ScheduledNotificationToSend:get_next()
 |