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 @ 1592:72d9219f2f19

History | View | Annotate | Download (5.45 KB)

1
# encoding: utf-8
2
#
3
# Redmine - project management software
4
# Copyright (C) 2006-2014  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

    
22
  def sort_activity_events(events)
23
    events_by_group = events.group_by(&:event_group)
24
    sorted_events = []
25
    events.sort {|x, y| y.event_datetime <=> x.event_datetime}.each do |event|
26
      if group_events = events_by_group.delete(event.event_group)
27
        group_events.sort {|x, y| y.event_datetime <=> x.event_datetime}.each_with_index do |e, i|
28
          sorted_events << [e, i > 0]
29
        end
30
      end
31
    end
32
    sorted_events
33
  end
34

    
35
  def date_of_event(e)
36
    if e.respond_to? :updated_at
37
      e.updated_at
38
    elsif e.respond_to? :updated_on
39
      e.updated_on
40
    elsif e.respond_to? :created_on
41
      e.created_on
42
    elsif e.respond_to? :committed_on
43
      e.committed_on
44
    else
45
      nil 
46
    end
47
  end
48

    
49
  def project_activity_on_events(events)
50

    
51
    # Score each project for which there are any events, by giving
52
    # each event a score based on how long ago it was (the more recent
53
    # the better). Return a hash mapping project id to score.
54

    
55
    projhash = Hash.new
56
    
57
    events.each do |e|
58
      if e.respond_to?(:project)
59
        p = e.project
60
        d = date_of_event e
61
        if !d.nil?
62
          dd = Date.parse d.to_s
63
          age = Date.today - dd
64
          score = (age < 14 ? 15-age : 1)
65
          if projhash.key? p
66
            projhash[p] += score
67
          else
68
            projhash[p] = score
69
          end
70
        end
71
      end
72
    end
73
    projhash
74
  end
75

    
76
  def projects_by_activity(user, count)
77

    
78
    # Return up to count of the user's project ids ordered by that user's
79
    # recent activity, omitting any projects for which no activity
80
    # occurred in the recent past and any projects not visible to
81
    # the current user
82

    
83
    activity = Redmine::Activity::Fetcher.new(User.current, :author => user)
84

    
85
    # Limit scope so as to exclude issues (which non-members can add)
86
    activity.scope = [ "changesets", "files", "documents", "news", "wiki_edits", "messages", "time_entries", "publications" ]
87

    
88
    days = Setting.activity_days_default.to_i
89
    events = activity.events(Date.today - days, Date.today + 1)
90
    projhash = project_activity_on_events(events)
91
    projhash.keys.sort_by { |k| -projhash[k] }.first(count)
92
  end
93

    
94
  def render_active_colleagues(colleagues)
95

    
96
    s = ""
97

    
98
    start = Time.now
99

    
100
    my_inst = ""
101
    if ! User.current.ssamr_user_detail.nil?
102
      my_inst = User.current.ssamr_user_detail.institution_name
103
    end
104

    
105
    actives = Hash.new
106
    for c in colleagues
107
      u = User.find_by_id(c)
108
      active_projects = projects_by_activity(u, 3)
109
      if !active_projects.empty?
110
        actives[c] = active_projects
111
      end
112
    end
113

    
114
    if actives.empty?
115
      l(:label_no_active_colleagues)
116
    else
117

    
118
      s << "<dl>"
119
      for c in actives.keys.sample(10)
120
        u = User.find_by_id(c)
121
        s << "<dt>"
122
        s << avatar(u, :size => '24')
123
        s << "<span class='user'>"
124
        s << h(u.name)
125
        s << "</span>"
126
        if !u.ssamr_user_detail.nil?
127
          inst = u.ssamr_user_detail.institution_name
128
          if inst != "" and inst != my_inst
129
            s << " - <span class='institution'>"
130
            s << h(u.ssamr_user_detail.institution_name)
131
            s << "</span>"
132
          end
133
        end
134
        s << "</dt>"
135
        s << "<dd>"
136
        s << "<span class='active'>"
137
        s << (actives[c].map { |p| link_to_project(p) }.join ", ")
138
        s << "</span>"
139
      end
140
      s << "</dl>"
141

    
142
      finish = Time.now
143
      logger.info "render_active_colleagues: took #{finish-start}"
144
    
145
      s.html_safe
146
    end
147
  end
148

    
149
  def busy_projects(events, count)
150

    
151
    # Return a list of count projects randomly selected from amongst
152
    # the busiest projects represented by the given activity events
153

    
154
    projhash = project_activity_on_events(events)
155

    
156
    # pick N highest values and use cutoff value as selection threshold
157
    threshold = projhash.values.sort.last(count).first
158

    
159
    # select projects above threshold and pick N from them randomly
160
    busy = projhash.keys.select { |k| projhash[k] >= threshold }.sample(count)
161

    
162
    # return projects rather than just ids
163
    busy.map { |pid| Project.find(pid) }
164
  end
165

    
166
  def busy_institutions(events, count)
167
    authors = events.map do |e|
168
      e.event_author unless !e.respond_to?(:event_author) 
169
    end.compact
170
    institutions = authors.map do |a|
171
      if a.respond_to?(:ssamr_user_detail) and !a.ssamr_user_detail.nil? and a.ssamr_user_detail.institution_name != "none"
172
        a.ssamr_user_detail.institution_name
173
      end
174
    end
175
    insthash = institutions.compact.sort.group_by { |i| i }
176
    insthash = insthash.merge(insthash) { |k,v| v.length }
177
    threshold = insthash.values.sort.last(count).first
178
    insthash.keys.select { |k| insthash[k] >= threshold }.sample(count)
179
  end
180

    
181
end