diff options
author | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2015-03-21 23:48:08 -0700 |
---|---|---|
committer | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2015-03-21 23:48:08 -0700 |
commit | 64891c6c40c6b670c2b50aab8ba56e3d47e30076 (patch) | |
tree | c0c02058708644a7b0287bdff10b30e23568bd3d | |
parent | 29f6b01d6343c08dc9fe1f6bdf95a645dd4e4cc0 (diff) | |
download | gitlab-ce-64891c6c40c6b670c2b50aab8ba56e3d47e30076.tar.gz |
Replace commits calendar with contributions calendar
* count opening of issues and merge requests
* dont trigger git repository - use events from database
* much-much faster since does not affected by repository size
-rw-r--r-- | app/assets/javascripts/calendar.js.coffee | 2 | ||||
-rw-r--r-- | app/controllers/users_controller.rb | 29 | ||||
-rw-r--r-- | app/models/project_contributions.rb | 32 | ||||
-rw-r--r-- | app/models/repository.rb | 35 | ||||
-rw-r--r-- | app/views/users/calendar.html.haml | 2 | ||||
-rw-r--r-- | app/views/users/calendar_activities.html.haml | 53 | ||||
-rw-r--r-- | lib/gitlab/commits_calendar.rb | 41 | ||||
-rw-r--r-- | lib/gitlab/contributions_calendar.rb | 65 |
8 files changed, 104 insertions, 155 deletions
diff --git a/app/assets/javascripts/calendar.js.coffee b/app/assets/javascripts/calendar.js.coffee index 2891a48e249..99e7d3a029f 100644 --- a/app/assets/javascripts/calendar.js.coffee +++ b/app/assets/javascripts/calendar.js.coffee @@ -7,7 +7,7 @@ class @calendar constructor: (timestamps, starting_year, starting_month, calendar_activities_path) -> cal = new CalHeatMap() cal.init - itemName: ["commit"] + itemName: ["contribution"] data: timestamps start: new Date(starting_year, starting_month) domainLabelFormat: "%b" diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 68130eb128c..f39c820626f 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -31,9 +31,7 @@ class UsersController < ApplicationController end def calendar - projects = Project.where(id: authorized_projects_ids & @user.contributed_projects_ids) - - calendar = Gitlab::CommitsCalendar.new(projects, @user) + calendar = contributions_calendar @timestamps = calendar.timestamps @starting_year = calendar.starting_year @starting_month = calendar.starting_month @@ -42,20 +40,13 @@ class UsersController < ApplicationController end def calendar_activities - projects = Project.where(id: authorized_projects_ids & @user.contributed_projects_ids) + @calendar_date = Date.parse(params[:date]) rescue nil + @events = [] - date = Date.parse(params[:date]) rescue nil - if date - @calendar_activities = Gitlab::CommitsCalendar.get_commits_for_date(projects, @user, date) - else - @calendar_activities = {} + if @calendar_date + @events = contributions_calendar.events_by_date(@calendar_date) end - # get the total number of unique commits - @commit_count = @calendar_activities.values.flatten.map(&:id).uniq.count - - @calendar_date = date - render 'calendar_activities', layout: false end @@ -82,4 +73,14 @@ class UsersController < ApplicationController @authorized_projects_ids ||= ProjectsFinder.new.execute(current_user).pluck(:id) end + + def contributed_projects + @contributed_projects = Project. + where(id: authorized_projects_ids & @user.contributed_projects_ids).reject(&:forked?) + end + + def contributions_calendar + @contributions_calendar ||= Gitlab::ContributionsCalendar. + new(contributed_projects, @user) + end end diff --git a/app/models/project_contributions.rb b/app/models/project_contributions.rb deleted file mode 100644 index bfe9928b158..00000000000 --- a/app/models/project_contributions.rb +++ /dev/null @@ -1,32 +0,0 @@ -class ProjectContributions - attr_reader :project, :user - - def initialize(project, user) - @project, @user = project, user - end - - def commits_log - repository = project.repository - - if !repository.exists? || repository.empty? - return {} - end - - Rails.cache.fetch(cache_key) do - repository.commits_per_day_for_user(user) - end - end - - def user_commits_on_date(date) - repository = @project.repository - - if !repository.exists? || repository.empty? - return [] - end - commits = repository.commits_by_user_on_date_log(@user, date) - end - - def cache_key - "#{Date.today.to_s}-commits-log-#{project.id}-#{user.email}" - end -end diff --git a/app/models/repository.rb b/app/models/repository.rb index 082ad7a0c6a..77765cae1a0 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -149,41 +149,6 @@ class Repository end end - def timestamps_by_user_log(user) - author_emails = '(' + user.all_emails.map{ |e| Regexp.escape(e) }.join('|') + ')' - args = %W(git log -E --author=#{author_emails} --since=#{(Date.today - 1.year).to_s} --branches --pretty=format:%cd --date=short) - dates = Gitlab::Popen.popen(args, path_to_repo).first.split("\n") - - if dates.present? - dates - else - [] - end - end - - def commits_by_user_on_date_log(user, date) - # format the date string for git - start_date = date.strftime("%Y-%m-%d 00:00:00") - end_date = date.strftime("%Y-%m-%d 23:59:59") - - author_emails = '(' + user.all_emails.map{ |e| Regexp.escape(e) }.join('|') + ')' - args = %W(git log -E --author=#{author_emails} --after=#{start_date.to_s} --until=#{end_date.to_s} --branches --pretty=format:%h) - commits = Gitlab::Popen.popen(args, path_to_repo).first.split("\n") - - commits.map! do |commit_id| - commit(commit_id) - end - end - - def commits_per_day_for_user(user) - timestamps_by_user_log(user). - group_by { |commit_date| commit_date }. - inject({}) do |hash, (timestamp_date, commits)| - hash[timestamp_date] = commits.count - hash - end - end - def lookup_cache @lookup_cache ||= {} end diff --git a/app/views/users/calendar.html.haml b/app/views/users/calendar.html.haml index d113ceeb753..12446a209f8 100644 --- a/app/views/users/calendar.html.haml +++ b/app/views/users/calendar.html.haml @@ -1,4 +1,4 @@ -%h4 Commits calendar +%h4 Contributions calendar #cal-heatmap.calendar :javascript new calendar( diff --git a/app/views/users/calendar_activities.html.haml b/app/views/users/calendar_activities.html.haml index 7c0cecfadb5..4200233dc4b 100644 --- a/app/views/users/calendar_activities.html.haml +++ b/app/views/users/calendar_activities.html.haml @@ -1,33 +1,24 @@ .calendar_commit_activity - %hr - %h4 - Commit Activity - %strong - - if @commit_count == 0 - no - - else - = @commit_count - %span.calendar_commit_date - unique - = 'commit'.pluralize(@commit_count) - on - = @calendar_date.strftime("%b %d, %Y") rescue '' - -unless @commit_count == 0 - %hr - - @calendar_activities.each do |project, commits| - - next if commits.empty? - %div.js-toggle-container +%h4.prepend-top-20 + %span.light Contributions for + %strong #{@calendar_date.to_s(:short)} + +%ul.bordered-list + - @events.sort_by(&:created_at).each do |event| + %li + %span.light + %i.fa.fa-clock-o + = event.created_at.to_s(:time) + - if event.push? && event.commits_count > 0 + pushed #{event.commits_count} commits to + - else + = event_action_name(event) + - if event.target + %strong= link_to "##{event.target_iid}", [event.project.namespace.becomes(Namespace), event.project, event.target] + at + %strong - = pluralize(commits.count, 'commit') - in project - = link_to project.name_with_namespace, project_path(project) - %a.text-expander.js-toggle-button … - %hr - %div.js-toggle-content - - commits.each do |commit| - %span.monospace - = commit.committed_date.strftime("%H:%M") - = link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit_short_id" - = link_to commit.message, namespace_project_commit_path(project.namespace, project, commit), class: "commit-row-message str-truncated" - %br - %hr + - if event.project + = link_to_project event.project + - else + = event.project_name diff --git a/lib/gitlab/commits_calendar.rb b/lib/gitlab/commits_calendar.rb deleted file mode 100644 index 8963d346b6f..00000000000 --- a/lib/gitlab/commits_calendar.rb +++ /dev/null @@ -1,41 +0,0 @@ -module Gitlab - class CommitsCalendar - attr_reader :timestamps - - def initialize(projects, user) - @timestamps = {} - date_timestamps = [] - - projects.reject(&:forked?).each do |project| - date_timestamps << ProjectContributions.new(project, user).commits_log - end - - # Sumarrize commits from all projects per days - date_timestamps = date_timestamps.inject do |collection, date| - collection.merge(date) { |k, old_v, new_v| old_v + new_v } - end - - date_timestamps ||= [] - date_timestamps.each do |date, commits| - timestamp = Date.parse(date).to_time.to_i.to_s rescue nil - @timestamps[timestamp] = commits if timestamp - end - end - - def self.get_commits_for_date(projects, user, date) - user_commits = {} - projects.reject(&:forked?).each do |project| - user_commits[project] = ProjectContributions.new(project, user).user_commits_on_date(date) - end - user_commits - end - - def starting_year - (Time.now - 1.year).strftime("%Y") - end - - def starting_month - Date.today.strftime("%m").to_i - end - end -end diff --git a/lib/gitlab/contributions_calendar.rb b/lib/gitlab/contributions_calendar.rb new file mode 100644 index 00000000000..8ca5115d43a --- /dev/null +++ b/lib/gitlab/contributions_calendar.rb @@ -0,0 +1,65 @@ +module Gitlab + class ContributionsCalendar + attr_reader :timestamps, :projects, :user + + def initialize(projects, user) + @projects = projects + @user = user + end + + def timestamps + return @timestamps if @timestamps.present? + + @timestamps = {} + date_from = 1.year.ago + date_to = Date.today + + events = Event.where(author_id: user.id).where(action: event_type). + where("created_at > ?", date_from).where(project_id: projects) + + grouped_events = events.to_a.group_by { |event| event.created_at.to_date.to_s } + dates = (1.year.ago.to_date..(Date.today + 1.day)).to_a + + dates.each do |date| + date_id = date.to_time.to_i.to_s + @timestamps[date_id] = 0 + + if grouped_events.has_key?(date.to_s) + grouped_events[date.to_s].each do |event| + if event.created_at.to_date == date + if event.issue? || event.merge_request? + @timestamps[date_id] += 1 + elsif event.push? + @timestamps[date_id] += event.commits_count + end + end + end + end + end + + @timestamps + end + + def events_by_date(date) + events = Event.where(author_id: user.id).where(action: event_type). + where("created_at > ? AND created_at < ?", date.beginning_of_day, date.end_of_day). + where(project_id: projects) + + events.select do |event| + event.push? || event.issue? || event.merge_request? + end + end + + def starting_year + (Time.now - 1.year).strftime("%Y") + end + + def starting_month + Date.today.strftime("%m").to_i + end + + def event_type + [Event::PUSHED, Event::CREATED, Event::CLOSED, Event::MERGED] + end + end +end |