annotate app/helpers/activities_helper.rb @ 1628:9c5f8e24dadc live tip

Quieten this cron script
author Chris Cannam
date Tue, 25 Aug 2020 11:38:49 +0100
parents afce8026aaeb
children
rev   line source
Chris@1464 1 # encoding: utf-8
Chris@1464 2 #
Chris@1464 3 # Redmine - project management software
Chris@1494 4 # Copyright (C) 2006-2014 Jean-Philippe Lang
Chris@1464 5 #
Chris@1464 6 # This program is free software; you can redistribute it and/or
Chris@1464 7 # modify it under the terms of the GNU General Public License
Chris@1464 8 # as published by the Free Software Foundation; either version 2
Chris@1464 9 # of the License, or (at your option) any later version.
Chris@1464 10 #
Chris@1464 11 # This program is distributed in the hope that it will be useful,
Chris@1464 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@1464 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@1464 14 # GNU General Public License for more details.
Chris@1464 15 #
Chris@1464 16 # You should have received a copy of the GNU General Public License
Chris@1464 17 # along with this program; if not, write to the Free Software
Chris@1464 18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
chris@1011 19
chris@1011 20 module ActivitiesHelper
chris@1011 21
Chris@1464 22 def sort_activity_events(events)
Chris@1464 23 events_by_group = events.group_by(&:event_group)
Chris@1464 24 sorted_events = []
Chris@1464 25 events.sort {|x, y| y.event_datetime <=> x.event_datetime}.each do |event|
Chris@1464 26 if group_events = events_by_group.delete(event.event_group)
Chris@1464 27 group_events.sort {|x, y| y.event_datetime <=> x.event_datetime}.each_with_index do |e, i|
Chris@1464 28 sorted_events << [e, i > 0]
Chris@1464 29 end
Chris@1464 30 end
Chris@1464 31 end
Chris@1464 32 sorted_events
Chris@1464 33 end
Chris@1484 34
chris@1205 35 def date_of_event(e)
chris@1205 36 if e.respond_to? :updated_at
chris@1205 37 e.updated_at
chris@1205 38 elsif e.respond_to? :updated_on
chris@1205 39 e.updated_on
chris@1205 40 elsif e.respond_to? :created_on
chris@1205 41 e.created_on
chris@1205 42 elsif e.respond_to? :committed_on
chris@1205 43 e.committed_on
chris@1205 44 else
chris@1205 45 nil
chris@1205 46 end
chris@1205 47 end
chris@1205 48
chris@1217 49 def project_activity_on_events(events)
chris@1186 50
chris@1186 51 # Score each project for which there are any events, by giving
chris@1186 52 # each event a score based on how long ago it was (the more recent
chris@1217 53 # the better). Return a hash mapping project id to score.
chris@1186 54
chris@1186 55 projhash = Hash.new
chris@1186 56
chris@1186 57 events.each do |e|
chris@1186 58 if e.respond_to?(:project)
chris@1186 59 p = e.project
chris@1205 60 d = date_of_event e
chris@1205 61 if !d.nil?
chris@1205 62 dd = Date.parse d.to_s
chris@1205 63 age = Date.today - dd
chris@1205 64 score = (age < 14 ? 15-age : 1)
chris@1205 65 if projhash.key? p
chris@1205 66 projhash[p] += score
chris@1205 67 else
chris@1205 68 projhash[p] = score
chris@1205 69 end
chris@1186 70 end
chris@1186 71 end
chris@1186 72 end
chris@1217 73 projhash
chris@1217 74 end
chris@1217 75
chris@1217 76 def projects_by_activity(user, count)
chris@1217 77
Chris@1227 78 # Return up to count of the user's project ids ordered by that user's
chris@1217 79 # recent activity, omitting any projects for which no activity
Chris@1219 80 # occurred in the recent past and any projects not visible to
Chris@1219 81 # the current user
chris@1217 82
Chris@1219 83 activity = Redmine::Activity::Fetcher.new(User.current, :author => user)
chris@1224 84
chris@1224 85 # Limit scope so as to exclude issues (which non-members can add)
chris@1224 86 activity.scope = [ "changesets", "files", "documents", "news", "wiki_edits", "messages", "time_entries", "publications" ]
chris@1224 87
chris@1217 88 days = Setting.activity_days_default.to_i
chris@1217 89 events = activity.events(Date.today - days, Date.today + 1)
chris@1217 90 projhash = project_activity_on_events(events)
chris@1217 91 projhash.keys.sort_by { |k| -projhash[k] }.first(count)
chris@1217 92 end
chris@1217 93
chris@1217 94 def render_active_colleagues(colleagues)
chris@1217 95
chris@1217 96 s = ""
chris@1217 97
chris@1222 98 start = Time.now
chris@1222 99
Chris@1226 100 my_inst = ""
Chris@1226 101 if ! User.current.ssamr_user_detail.nil?
Chris@1226 102 my_inst = User.current.ssamr_user_detail.institution_name
Chris@1226 103 end
Chris@1226 104
Chris@1227 105 actives = Hash.new
chris@1217 106 for c in colleagues
chris@1217 107 u = User.find_by_id(c)
chris@1217 108 active_projects = projects_by_activity(u, 3)
chris@1217 109 if !active_projects.empty?
Chris@1227 110 actives[c] = active_projects
Chris@1227 111 end
Chris@1227 112 end
Chris@1227 113
Chris@1227 114 if actives.empty?
Chris@1227 115 l(:label_no_active_colleagues)
Chris@1227 116 else
Chris@1227 117
Chris@1227 118 s << "<dl>"
Chris@1227 119 for c in actives.keys.sample(10)
Chris@1227 120 u = User.find_by_id(c)
chris@1224 121 s << "<dt>"
Chris@1219 122 s << avatar(u, :size => '24')
Chris@1219 123 s << "<span class='user'>"
Chris@1219 124 s << h(u.name)
chris@1217 125 s << "</span>"
Chris@1219 126 if !u.ssamr_user_detail.nil?
Chris@1226 127 inst = u.ssamr_user_detail.institution_name
Chris@1226 128 if inst != "" and inst != my_inst
Chris@1226 129 s << " - <span class='institution'>"
Chris@1226 130 s << h(u.ssamr_user_detail.institution_name)
Chris@1226 131 s << "</span>"
Chris@1226 132 end
Chris@1219 133 end
chris@1224 134 s << "</dt>"
chris@1224 135 s << "<dd>"
Chris@1219 136 s << "<span class='active'>"
Chris@1227 137 s << (actives[c].map { |p| link_to_project(p) }.join ", ")
Chris@1219 138 s << "</span>"
chris@1217 139 end
Chris@1227 140 s << "</dl>"
chris@1222 141
Chris@1227 142 finish = Time.now
Chris@1227 143 logger.info "render_active_colleagues: took #{finish-start}"
chris@1217 144
Chris@1330 145 s.html_safe
chris@1217 146 end
chris@1217 147 end
chris@1217 148
chris@1217 149 def busy_projects(events, count)
chris@1217 150
chris@1217 151 # Return a list of count projects randomly selected from amongst
chris@1217 152 # the busiest projects represented by the given activity events
chris@1217 153
chris@1217 154 projhash = project_activity_on_events(events)
chris@1217 155
chris@1186 156 # pick N highest values and use cutoff value as selection threshold
chris@1186 157 threshold = projhash.values.sort.last(count).first
chris@1186 158
chris@1186 159 # select projects above threshold and pick N from them randomly
chris@1186 160 busy = projhash.keys.select { |k| projhash[k] >= threshold }.sample(count)
chris@1186 161
chris@1186 162 # return projects rather than just ids
chris@1011 163 busy.map { |pid| Project.find(pid) }
chris@1011 164 end
chris@1011 165
chris@1011 166 def busy_institutions(events, count)
Chris@1013 167 authors = events.map do |e|
Chris@1013 168 e.event_author unless !e.respond_to?(:event_author)
Chris@1013 169 end.compact
Chris@1013 170 institutions = authors.map do |a|
Chris@1499 171 if a.respond_to?(:ssamr_user_detail) and !a.ssamr_user_detail.nil? and a.ssamr_user_detail.institution_name != "none"
Chris@1013 172 a.ssamr_user_detail.institution_name
Chris@1013 173 end
Chris@1013 174 end
chris@1011 175 insthash = institutions.compact.sort.group_by { |i| i }
chris@1011 176 insthash = insthash.merge(insthash) { |k,v| v.length }
chris@1011 177 threshold = insthash.values.sort.last(count).first
chris@1011 178 insthash.keys.select { |k| insthash[k] >= threshold }.sample(count)
chris@1011 179 end
chris@1011 180
chris@1011 181 end