To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / app / helpers / activities_helper.rb @ 1298:4f746d8966dd

History | View | Annotate | Download (5.4 KB)

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