summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSean McGivern <sean@gitlab.com>2017-04-12 12:19:45 +0100
committerRémy Coutable <remy@rymai.me>2017-04-14 15:20:55 +0200
commit91ac0e038ab51dd2f30f2bb7c91837fa588ca250 (patch)
tree54b5ea7cb6115a09bbcead558252563664b4898c /lib
parent3cb84e06b7a118fb46b4e1e0d4885026c9d4a4d1 (diff)
downloadgitlab-ce-91ac0e038ab51dd2f30f2bb7c91837fa588ca250.tar.gz
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.rb5
-rw-r--r--lib/api/issues.rb2
-rw-r--r--lib/api/users.rb18
-rw-r--r--lib/gitlab/pagination_delegate.rb65
-rw-r--r--lib/gitlab/user_activities/activity.rb16
-rw-r--r--lib/gitlab/user_activities/activity_set.rb67
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