diff options
author | Sean McGivern <sean@gitlab.com> | 2017-04-12 14:19:45 +0300 |
---|---|---|
committer | Rémy Coutable <remy@rymai.me> | 2017-04-14 16:20:55 +0300 |
commit | 91ac0e038ab51dd2f30f2bb7c91837fa588ca250 (patch) | |
tree | 54b5ea7cb6115a09bbcead558252563664b4898c /lib | |
parent | 3cb84e06b7a118fb46b4e1e0d4885026c9d4a4d1 (diff) |
Port 'Add user activities API' to CE
CE port of https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/962
Diffstat (limited to 'lib')
-rw-r--r-- | lib/api/entities.rb | 5 | ||||
-rw-r--r-- | lib/api/issues.rb | 2 | ||||
-rw-r--r-- | lib/api/users.rb | 18 | ||||
-rw-r--r-- | lib/gitlab/pagination_delegate.rb | 65 | ||||
-rw-r--r-- | lib/gitlab/user_activities/activity.rb | 16 | ||||
-rw-r--r-- | lib/gitlab/user_activities/activity_set.rb | 67 |
6 files changed, 172 insertions, 1 deletions
diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 9919762cd82..939cedc1b27 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -18,6 +18,11 @@ module API expose :bio, :location, :skype, :linkedin, :twitter, :website_url, :organization end + class UserActivity < Grape::Entity + expose :username + expose :last_activity_at + end + class Identity < Grape::Entity expose :provider, :extern_uid end diff --git a/lib/api/issues.rb b/lib/api/issues.rb index 05423c17449..244725bb292 100644 --- a/lib/api/issues.rb +++ b/lib/api/issues.rb @@ -35,7 +35,7 @@ module API optional :assignee_id, type: Integer, desc: 'The ID of a user to assign issue' optional :milestone_id, type: Integer, desc: 'The ID of a milestone to assign issue' optional :labels, type: String, desc: 'Comma-separated list of label names' - optional :due_date, type: String, desc: 'Date time string in the format YEAR-MONTH-DAY' + optional :due_date, type: String, desc: 'Date string in the format YEAR-MONTH-DAY' optional :confidential, type: Boolean, desc: 'Boolean parameter if the issue should be confidential' end diff --git a/lib/api/users.rb b/lib/api/users.rb index eedc59f8636..16fa1ef6836 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -534,6 +534,24 @@ module API email.destroy current_user.update_secondary_emails! end + + + desc 'Get a list of user activities' + params do + optional :from, type: String, desc: 'Date string in the format YEAR-MONTH-DAY' + use :pagination + end + get ":activities" do + authenticated_as_admin! + + activity_set = Gitlab::UserActivities::ActivitySet.new(from: params[:from], + page: params[:page], + per_page: params[:per_page]) + + add_pagination_headers(activity_set) + + present activity_set.activities, with: Entities::UserActivity + end end end end diff --git a/lib/gitlab/pagination_delegate.rb b/lib/gitlab/pagination_delegate.rb new file mode 100644 index 00000000000..d4913e908b2 --- /dev/null +++ b/lib/gitlab/pagination_delegate.rb @@ -0,0 +1,65 @@ +module Gitlab + class PaginationDelegate + DEFAULT_PER_PAGE = Kaminari.config.default_per_page + MAX_PER_PAGE = Kaminari.config.max_per_page + + def initialize(page:, per_page:, count:, options: {}) + @count = count + @options = { default_per_page: DEFAULT_PER_PAGE, + max_per_page: MAX_PER_PAGE }.merge(options) + + @per_page = sanitize_per_page(per_page) + @page = sanitize_page(page) + end + + def total_count + @count + end + + def total_pages + (total_count.to_f / @per_page).ceil + end + + def next_page + current_page + 1 unless last_page? + end + + def prev_page + current_page - 1 unless first_page? + end + + def current_page + @page + end + + def limit_value + @per_page + end + + def first_page? + current_page == 1 + end + + def last_page? + current_page >= total_pages + end + + def offset + (current_page - 1) * limit_value + end + + private + + def sanitize_per_page(per_page) + return @options[:default_per_page] unless per_page && per_page > 0 + + [@options[:max_per_page], per_page].min + end + + def sanitize_page(page) + return 1 unless page && page > 1 + + [total_pages, page].min + end + end +end diff --git a/lib/gitlab/user_activities/activity.rb b/lib/gitlab/user_activities/activity.rb new file mode 100644 index 00000000000..ec052870ee3 --- /dev/null +++ b/lib/gitlab/user_activities/activity.rb @@ -0,0 +1,16 @@ +module Gitlab + module UserActivities + class Activity + attr_reader :username + + def initialize(username, time) + @username = username + @time = time + end + + def last_activity_at + @last_activity_at ||= Time.at(@time).to_s(:db) + end + end + end +end diff --git a/lib/gitlab/user_activities/activity_set.rb b/lib/gitlab/user_activities/activity_set.rb new file mode 100644 index 00000000000..6b8e540e99b --- /dev/null +++ b/lib/gitlab/user_activities/activity_set.rb @@ -0,0 +1,67 @@ +module Gitlab + module UserActivities + class ActivitySet + delegate :total_count, + :total_pages, + :current_page, + :limit_value, + :first_page?, + :prev_page, + :last_page?, + :next_page, to: :pagination_delegate + + KEY = 'user/activities' + + def self.record(user) + Gitlab::Redis.with do |redis| + redis.zadd(KEY, Time.now.to_i, user.username) + end + end + + def initialize(from: nil, page: nil, per_page: nil) + @from = sanitize_date(from) + @to = Time.now.to_i + @page = page + @per_page = per_page + end + + def activities + @activities ||= raw_activities.map { |activity| Activity.new(*activity) } + end + + private + + def sanitize_date(date) + Time.strptime(date, "%Y-%m-%d").to_i + rescue TypeError, ArgumentError + default_from + end + + def pagination_delegate + @pagination_delegate ||= Gitlab::PaginationDelegate.new(page: @page, + per_page: @per_page, + count: count) + end + + def raw_activities + Gitlab::Redis.with do |redis| + redis.zrangebyscore(KEY, @from, @to, with_scores: true, limit: limit) + end + end + + def count + Gitlab::Redis.with do |redis| + redis.zcount(KEY, @from, @to) + end + end + + def limit + [pagination_delegate.offset, pagination_delegate.limit_value] + end + + def default_from + 6.months.ago.to_i + end + end + end +end |