friends_controller.rb 1.88 KB
Newer Older
Eugen Rochko's avatar
Eugen Rochko committed
1 2
# frozen_string_literal: true

Eugen Rochko's avatar
Eugen Rochko committed
3 4 5 6
require 'twitter'

class FriendsController < ApplicationController
  before_action :authenticate_user!
Eugen Rochko's avatar
Eugen Rochko committed
7 8
  before_action :set_friends, only: :index
  before_action :set_top_instances, only: :index
Eugen Rochko's avatar
Eugen Rochko committed
9

Eugen Rochko's avatar
Eugen Rochko committed
10 11 12 13
  rescue_from Twitter::Error do |e|
    redirect_to root_path, alert: "Twitter error: #{e}"
  end

Eugen Rochko's avatar
Eugen Rochko committed
14
  def index; end
15

Eugen Rochko's avatar
Eugen Rochko committed
16 17
  private

Eugen Rochko's avatar
Eugen Rochko committed
18 19 20 21
  def set_friends
    @friends = User.where(id: Authorization.where(provider: :twitter, uid: twitter_friend_ids).map(&:user_id))
                   .includes(:authorizations)
                   .reject { |user| user.mastodon.nil? }
Eugen Rochko's avatar
Eugen Rochko committed
22 23
  end

Eugen Rochko's avatar
Eugen Rochko committed
24 25 26 27 28 29 30
  def set_top_instances
    @top_instances = @friends.collect { |user| user&.mastodon&.uid }
                             .compact
                             .map { |uid| uid.split('@').last }
                             .inject(Hash.new(0)) { |h, k| h[k] += 1; h }
                             .sort_by { |k, v| v }
                             .map { |k, _| Rails.cache.fetch("instance:#{k}", expires_in: 1.week) { Oj.load(HTTP.get("https://#{k}/api/v1/instance").to_s) } }
31 32
  end

Eugen Rochko's avatar
Eugen Rochko committed
33 34
  def twitter_friend_ids
    Rails.cache.fetch("#{current_user.id}/twitter-friends", expires_in: 15.minutes) { twitter_client.friend_ids.to_a }
Eugen Rochko's avatar
Eugen Rochko committed
35 36 37 38 39 40 41 42 43 44 45 46
  end

  def twitter_client
    @twitter_client ||= Twitter::REST::Client.new do |config|
      authorization = current_user.authorizations.find_by(provider: :twitter)

      config.consumer_key        = ENV['TWITTER_CLIENT_ID']
      config.consumer_secret     = ENV['TWITTER_CLIENT_SECRET']
      config.access_token        = authorization.try(:token)
      config.access_token_secret = authorization.try(:secret)
    end
  end
47 48 49 50 51 52

  def mastodon_client
    authorization = current_user.authorizations.find_by(provider: :mastodon)
    _, domain = authorization.uid.split('@')
    @mastodon_client ||= Mastodon::REST::Client.new(base_url: "https://#{domain}", bearer_token: authorization.token)
  end
Eugen Rochko's avatar
Eugen Rochko committed
53
end