about summary refs log tree commit diff
path: root/app/controllers/api/v1
diff options
context:
space:
mode:
Diffstat (limited to 'app/controllers/api/v1')
-rw-r--r--app/controllers/api/v1/accounts_controller.rb14
-rw-r--r--app/controllers/api/v1/notifications_controller.rb24
-rw-r--r--app/controllers/api/v1/statuses_controller.rb15
-rw-r--r--app/controllers/api/v1/timelines_controller.rb31
4 files changed, 76 insertions, 8 deletions
diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb
index 2dfab0831..97d626af2 100644
--- a/app/controllers/api/v1/accounts_controller.rb
+++ b/app/controllers/api/v1/accounts_controller.rb
@@ -18,9 +18,11 @@ class Api::V1::AccountsController < ApiController
 
   def following
     results   = Follow.where(account: @account).paginate_by_max_id(DEFAULT_ACCOUNTS_LIMIT, params[:max_id], params[:since_id])
-    accounts  = Account.where(id: results.map(&:target_account_id)).with_counters.map { |a| [a.id, a] }.to_h
+    accounts  = Account.where(id: results.map(&:target_account_id)).map { |a| [a.id, a] }.to_h
     @accounts = results.map { |f| accounts[f.target_account_id] }
 
+    set_account_counters_maps(@accounts)
+
     next_path = following_api_v1_account_url(max_id: results.last.id)    if results.size == DEFAULT_ACCOUNTS_LIMIT
     prev_path = following_api_v1_account_url(since_id: results.first.id) unless results.empty?
 
@@ -31,9 +33,11 @@ class Api::V1::AccountsController < ApiController
 
   def followers
     results   = Follow.where(target_account: @account).paginate_by_max_id(DEFAULT_ACCOUNTS_LIMIT, params[:max_id], params[:since_id])
-    accounts  = Account.where(id: results.map(&:account_id)).with_counters.map { |a| [a.id, a] }.to_h
+    accounts  = Account.where(id: results.map(&:account_id)).map { |a| [a.id, a] }.to_h
     @accounts = results.map { |f| accounts[f.account_id] }
 
+    set_account_counters_maps(@accounts)
+
     next_path = followers_api_v1_account_url(max_id: results.last.id)    if results.size == DEFAULT_ACCOUNTS_LIMIT
     prev_path = followers_api_v1_account_url(since_id: results.first.id) unless results.empty?
 
@@ -53,9 +57,10 @@ class Api::V1::AccountsController < ApiController
   end
 
   def statuses
-    @statuses = @account.statuses.with_includes.with_counters.paginate_by_max_id(DEFAULT_STATUSES_LIMIT, params[:max_id], params[:since_id]).to_a
+    @statuses = @account.statuses.with_includes.paginate_by_max_id(DEFAULT_STATUSES_LIMIT, params[:max_id], params[:since_id]).to_a
 
     set_maps(@statuses)
+    set_counters_maps(@statuses)
 
     next_path = statuses_api_v1_account_url(max_id: @statuses.last.id)    if @statuses.size == DEFAULT_STATUSES_LIMIT
     prev_path = statuses_api_v1_account_url(since_id: @statuses.first.id) unless @statuses.empty?
@@ -98,6 +103,9 @@ class Api::V1::AccountsController < ApiController
   def search
     limit = params[:limit] ? [DEFAULT_ACCOUNTS_LIMIT, params[:limit].to_i].min : DEFAULT_ACCOUNTS_LIMIT
     @accounts = SearchService.new.call(params[:q], limit, params[:resolve] == 'true')
+
+    set_account_counters_maps(@accounts)
+
     render action: :index
   end
 
diff --git a/app/controllers/api/v1/notifications_controller.rb b/app/controllers/api/v1/notifications_controller.rb
index c76189e87..d74b99a86 100644
--- a/app/controllers/api/v1/notifications_controller.rb
+++ b/app/controllers/api/v1/notifications_controller.rb
@@ -7,7 +7,8 @@ class Api::V1::NotificationsController < ApiController
   respond_to :json
 
   def index
-    @notifications = Notification.where(account: current_account).with_includes.paginate_by_max_id(20, params[:max_id], params[:since_id])
+    @notifications = Notification.where(account: current_account).paginate_by_max_id(20, params[:max_id], params[:since_id])
+    @notifications = cache(@notifications)
     statuses       = @notifications.select { |n| !n.target_status.nil? }.map(&:target_status)
 
     set_maps(statuses)
@@ -19,4 +20,25 @@ class Api::V1::NotificationsController < ApiController
 
     set_pagination_headers(next_path, prev_path)
   end
+
+  private
+
+  def cache(raw)
+    uncached_ids           = []
+    cached_keys_with_value = Rails.cache.read_multi(*raw.map(&:cache_key))
+
+    raw.each do |notification|
+      uncached_ids << notification.id unless cached_keys_with_value.key?(notification.cache_key)
+    end
+
+    unless uncached_ids.empty?
+      uncached = Notification.where(id: uncached_ids).with_includes.map { |n| [n.id, n] }.to_h
+
+      uncached.values.each do |notification|
+        Rails.cache.write(notification.cache_key, notification)
+      end
+    end
+
+    raw.map { |notification| cached_keys_with_value[notification.cache_key] || uncached[notification.id] }
+  end
 end
diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb
index 53578b2f7..b2b432a6b 100644
--- a/app/controllers/api/v1/statuses_controller.rb
+++ b/app/controllers/api/v1/statuses_controller.rb
@@ -13,14 +13,19 @@ class Api::V1::StatusesController < ApiController
 
   def context
     @context = OpenStruct.new(ancestors: @status.ancestors(current_account), descendants: @status.descendants(current_account))
-    set_maps([@status] + @context[:ancestors] + @context[:descendants])
+    statuses = [@status] + @context[:ancestors] + @context[:descendants]
+
+    set_maps(statuses)
+    set_counters_maps(statuses)
   end
 
   def reblogged_by
     results   = @status.reblogs.paginate_by_max_id(DEFAULT_ACCOUNTS_LIMIT, params[:max_id], params[:since_id])
-    accounts  = Account.where(id: results.map(&:account_id)).with_counters.map { |a| [a.id, a] }.to_h
+    accounts  = Account.where(id: results.map(&:account_id)).map { |a| [a.id, a] }.to_h
     @accounts = results.map { |r| accounts[r.account_id] }
 
+    set_account_counters_maps(@accounts)
+
     next_path = reblogged_by_api_v1_status_url(max_id: results.last.id)    if results.size == DEFAULT_ACCOUNTS_LIMIT
     prev_path = reblogged_by_api_v1_status_url(since_id: results.first.id) unless results.empty?
 
@@ -31,9 +36,11 @@ class Api::V1::StatusesController < ApiController
 
   def favourited_by
     results   = @status.favourites.paginate_by_max_id(DEFAULT_ACCOUNTS_LIMIT, params[:max_id], params[:since_id])
-    accounts  = Account.where(id: results.map(&:account_id)).with_counters.map { |a| [a.id, a] }.to_h
+    accounts  = Account.where(id: results.map(&:account_id)).map { |a| [a.id, a] }.to_h
     @accounts = results.map { |f| accounts[f.account_id] }
 
+    set_account_counters_maps(@accounts)
+
     next_path = favourited_by_api_v1_status_url(max_id: results.last.id)    if results.size == DEFAULT_ACCOUNTS_LIMIT
     prev_path = favourited_by_api_v1_status_url(since_id: results.first.id) unless results.empty?
 
@@ -54,7 +61,7 @@ class Api::V1::StatusesController < ApiController
   end
 
   def reblog
-    @status = ReblogService.new.call(current_user.account, Status.find(params[:id])).reload
+    @status = ReblogService.new.call(current_user.account, Status.find(params[:id]))
     render action: :show
   end
 
diff --git a/app/controllers/api/v1/timelines_controller.rb b/app/controllers/api/v1/timelines_controller.rb
index 19b76f11d..b1d7c3052 100644
--- a/app/controllers/api/v1/timelines_controller.rb
+++ b/app/controllers/api/v1/timelines_controller.rb
@@ -10,6 +10,8 @@ class Api::V1::TimelinesController < ApiController
     @statuses = Feed.new(:home, current_account).get(DEFAULT_STATUSES_LIMIT, params[:max_id], params[:since_id]).to_a
 
     set_maps(@statuses)
+    set_counters_maps(@statuses)
+    set_account_counters_maps(@statuses.flat_map { |s| [s.account, s.reblog? ? s.reblog.account : nil] }.compact.uniq)
 
     next_path = api_v1_home_timeline_url(max_id: @statuses.last.id)    if @statuses.size == DEFAULT_STATUSES_LIMIT
     prev_path = api_v1_home_timeline_url(since_id: @statuses.first.id) unless @statuses.empty?
@@ -23,6 +25,8 @@ class Api::V1::TimelinesController < ApiController
     @statuses = Feed.new(:mentions, current_account).get(DEFAULT_STATUSES_LIMIT, params[:max_id], params[:since_id]).to_a
 
     set_maps(@statuses)
+    set_counters_maps(@statuses)
+    set_account_counters_maps(@statuses.flat_map { |s| [s.account, s.reblog? ? s.reblog.account : nil] }.compact.uniq)
 
     next_path = api_v1_mentions_timeline_url(max_id: @statuses.last.id)    if @statuses.size == DEFAULT_STATUSES_LIMIT
     prev_path = api_v1_mentions_timeline_url(since_id: @statuses.first.id) unless @statuses.empty?
@@ -34,8 +38,11 @@ class Api::V1::TimelinesController < ApiController
 
   def public
     @statuses = Status.as_public_timeline(current_account).paginate_by_max_id(DEFAULT_STATUSES_LIMIT, params[:max_id], params[:since_id]).to_a
+    @statuses = cache(@statuses)
 
     set_maps(@statuses)
+    set_counters_maps(@statuses)
+    set_account_counters_maps(@statuses.flat_map { |s| [s.account, s.reblog? ? s.reblog.account : nil] }.compact.uniq)
 
     next_path = api_v1_public_timeline_url(max_id: @statuses.last.id)    if @statuses.size == DEFAULT_STATUSES_LIMIT
     prev_path = api_v1_public_timeline_url(since_id: @statuses.first.id) unless @statuses.empty?
@@ -48,8 +55,11 @@ class Api::V1::TimelinesController < ApiController
   def tag
     @tag      = Tag.find_by(name: params[:id].downcase)
     @statuses = @tag.nil? ? [] : Status.as_tag_timeline(@tag, current_account).paginate_by_max_id(DEFAULT_STATUSES_LIMIT, params[:max_id], params[:since_id]).to_a
+    @statuses = cache(@statuses)
 
     set_maps(@statuses)
+    set_counters_maps(@statuses)
+    set_account_counters_maps(@statuses.flat_map { |s| [s.account, s.reblog? ? s.reblog.account : nil] }.compact.uniq)
 
     next_path = api_v1_hashtag_timeline_url(params[:id], max_id: @statuses.last.id)    if @statuses.size == DEFAULT_STATUSES_LIMIT
     prev_path = api_v1_hashtag_timeline_url(params[:id], since_id: @statuses.first.id) unless @statuses.empty?
@@ -58,4 +68,25 @@ class Api::V1::TimelinesController < ApiController
 
     render action: :index
   end
+
+  private
+
+  def cache(raw)
+    uncached_ids           = []
+    cached_keys_with_value = Rails.cache.read_multi(*raw.map(&:cache_key))
+
+    raw.each do |status|
+      uncached_ids << status.id unless cached_keys_with_value.key?(status.cache_key)
+    end
+
+    unless uncached_ids.empty?
+      uncached = Status.where(id: uncached_ids).with_includes.map { |s| [s.id, s] }.to_h
+
+      uncached.values.each do |status|
+        Rails.cache.write(status.cache_key, status)
+      end
+    end
+
+    raw.map { |status| cached_keys_with_value[status.cache_key] || uncached[status.id] }
+  end
 end