class ConnectedDevelopers
Attributes
developers[R]
Public Class Methods
new(developers:, twitter_client:, github_client: @twitter_client = twitter_client)
click to toggle source
# File lib/developer_cliques/connected_developers.rb, line 11 def initialize developers:, twitter_client:, github_client: @twitter_client = twitter_client @github_client = github_client @developers = developers @organizations = {} end
Public Instance Methods
followers(user_name)
click to toggle source
# File lib/developer_cliques/connected_developers.rb, line 28 def followers user_name follow_list = twitter_retry { @twitter_client.followers(user_name).entries.map{ |u| u.screen_name } } AppLogger.debug "FRIENDS: #{follow_list}" follow_list end
friends(user_name)
click to toggle source
# File lib/developer_cliques/connected_developers.rb, line 22 def friends user_name friends_list = twitter_retry { @twitter_client.friends(user_name).entries.map{ |u| u.screen_name } } AppLogger.debug "FRIENDS: #{friends_list}" friends_list end
graph()
click to toggle source
# File lib/developer_cliques/connected_developers.rb, line 18 def graph @graph ||= generate_graph end
organizations(user_name)
click to toggle source
# File lib/developer_cliques/connected_developers.rb, line 34 def organizations user_name @organizations[user_name] ||= @github_client.organizations(user_name).map{ |u| u.login } end
Private Instance Methods
generate_graph()
click to toggle source
# File lib/developer_cliques/connected_developers.rb, line 40 def generate_graph developers_graph = {} excluded = [] promises = developers.map do |developer| excluded << developer developers_graph[developer] ||= [] graph_by_developer developers_graph: developers_graph, developer: developer, excluded: excluded.clone end Concurrent::Promise.all?(*promises).execute.wait! developers_graph end
graph_by_developer(developers_graph:, developer:, excluded: AppLogger.debug "GITHUB USER:
click to toggle source
# File lib/developer_cliques/connected_developers.rb, line 55 def graph_by_developer developers_graph:, developer:, excluded: AppLogger.debug "GITHUB USER: #{developer}" AppLogger.debug "ORGANIZATIONS: #{organizations(developer)}" Concurrent::Promise.new { graph_by_organization developers_graph: developers_graph, remaining_devs: developers-excluded, current_developer: developer }.then{ |relationships| developers_graph[developer] = twitter_friendships developer: developer, relationships: relationships } end
graph_by_organization(developers_graph:, remaining_devs:, current_developer: AppLogger.debug "REMAINING DEVS:
click to toggle source
# File lib/developer_cliques/connected_developers.rb, line 68 def graph_by_organization developers_graph:, remaining_devs:, current_developer: #Bidireccional relationship. It excludes iterated developers and itself. We look only in one way AppLogger.debug "REMAINING DEVS: #{remaining_devs}" remaining_devs.each do |related_developer| # Intersection between organizations if there are some organization in common goes in unless (organizations(current_developer) & organizations(related_developer)).empty? #It creates relationship in one direction developers_graph[current_developer] << related_developer # And reverse direction developers_graph[related_developer] ||= [] developers_graph[related_developer] << current_developer end end developers_graph[current_developer] end
twitter_friendships(developer:, relationships: relationships &= friends(developer) & followers(developer) unless relationships.empty?)
click to toggle source
# File lib/developer_cliques/connected_developers.rb, line 84 def twitter_friendships developer:, relationships: #Intersection between friends, followers and current relationships by organizations in common relationships &= friends(developer) & followers(developer) unless relationships.empty? relationships end
twitter_retry() { || ... }
click to toggle source
# File lib/developer_cliques/connected_developers.rb, line 90 def twitter_retry &block begin yield rescue Twitter::Error::TooManyRequests => error # NOTE: Your process could go to sleep for up to 15 minutes but if you # retry any sooner, it will almost certainly fail with the same exception. AppLogger.debug "TOO MANY REQUEST: #{error}. Must wait #{error.rate_limit.reset_in/60} min" sleep error.rate_limit.reset_in + 1 retry end end