Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial pass at repo source rank #477 #1020

Merged
merged 1 commit into from
Dec 28, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/controllers/github_repositories_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ def show
@manifests = @github_repository.manifests.latest.limit(10).includes(repository_dependencies: {project: :versions})
end

def sourcerank
load_repo
end

def tags
load_repo
@tags = @github_repository.github_tags.published.order('published_at DESC, name DESC').paginate(page: page_number)
Expand Down
6 changes: 4 additions & 2 deletions app/helpers/sourcerank_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ def source_rank_titles
dependent_projects: 'Dependent Projects',
dependent_repositories: 'Dependent Repositories',
contributors: 'Contributors',
subscribers: 'Libraries.io subscribers'
subscribers: 'Libraries.io subscribers',
recently_pushed: 'Recently pushed?'
}
end

Expand All @@ -49,7 +50,8 @@ def source_rank_explainations
dependent_projects: 'Logarithmic scale times two',
dependent_repositories: 'Logarithmic scale',
contributors: 'Logarithmic scale divided by two',
subscribers: 'Logarithmic scale divided by two'
subscribers: 'Logarithmic scale divided by two',
recently_pushed: 'Pushed to within the past 6 months?'
}
end
end
76 changes: 76 additions & 0 deletions app/models/concerns/repository_source_rank.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
module RepositorySourceRank
extend ActiveSupport::Concern

def update_source_rank
update_column :rank, source_rank
touch
__elasticsearch__.index_document
end

def update_source_rank_async
UpdateRepositorySourceRankWorker.perform_async(self.id) if updated_at.present? && updated_at < 1.day.ago
end

def set_source_rank
self.rank = source_rank
end

def source_rank
source_rank_breakdown.values.sum > 0 ? source_rank_breakdown.values.sum : 0
end

def source_rank_breakdown
@source_rank_breakdown ||= {
basic_info_present: basic_info_present? ? 1 : 0,
readme_present: readme_present? ? 1 : 0,
license_present: license_present? ? 1 : 0,
recently_pushed: recently_pushed? ? 1 : 0,
not_brand_new: not_brand_new? ? 1 : 0,
dependent_projects: log_scale(dependent_projects_count) * 2,
dependent_repositories: log_scale(dependent_repos_count),
github_stars: log_scale(stars),
contributors: (log_scale(github_contributions_count) / 2.0).ceil,
any_outdated_dependencies: any_outdated_dependencies? ? -1 : 0,
is_deprecated: is_deprecated? ? -5 : 0,
is_unmaintained: is_unmaintained? ? -5 : 0,
is_removed: is_removed? ? -5 : 0
}
end

def basic_info_present?
[description.presence, homepage.presence].compact.length > 1
end

def readme_present?
readme.present?
end

def dependent_projects_count
projects.map(&:dependents_count).sum || 0
end

def dependent_repos_count
projects.map(&:dependent_repos_count).sum || 0
end

def license_present?
license.present?
end

def recently_pushed?
pushed_at && pushed_at > 6.months.ago
end

def not_brand_new?
created_at && created_at < 6.months.ago
end

def any_outdated_dependencies?
dependencies.any?(&:outdated?)
end

def log_scale(number)
return 0 if number <= 0
Math.log10(number).round
end
end
1 change: 1 addition & 0 deletions app/models/github_repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ class GithubRepository < ApplicationRecord
include RepoUrls
include RepoManifests
include RepoTags
include RepositorySourceRank

IGNORABLE_GITHUB_EXCEPTIONS = [Octokit::Unauthorized, Octokit::InvalidRepository, Octokit::RepositoryUnavailable, Octokit::NotFound, Octokit::Conflict, Octokit::Forbidden, Octokit::InternalServerError, Octokit::BadGateway, Octokit::ClientError]

Expand Down
54 changes: 54 additions & 0 deletions app/views/github_repositories/sourcerank.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<% title "SourceRank Breakdown for #{@github_repository} on GitHub - Libraries.io" %>

<div class="row">
<div class="col-md-12">
<h1><i class="fa fa-star"></i> SourceRank Breakdown for <%= link_to @github_repository, github_repository_path(@github_repository.owner_name, @github_repository.project_name) %></h1>
</div>
</div>
<hr>

<div class="row">
<% cache(['SourceRank', @github_repository]) do %>
<% @breakdown = @github_repository.source_rank_breakdown %>
<div class="col-sm-8">
<%= render 'adsense/banner' %>
<ul class="list-group">
<% @breakdown.each do |key, value| %>
<li class="list-group-item">
<span class="badge <%= source_rank_badge_class(value) %>">
<%= value %>
</span>
<%= source_rank_titles[key] || key %>
<% if source_rank_explainations[key].present? %>
&nbsp;<small class='text-muted'><%= fa_icon('question-circle', title: source_rank_explainations[key], class: 'tip') %></small>
<% end %>
</li>
<% end %>
<li class='list-group-item'>
<span class='badge alert-info'>
<%= @breakdown.values.sum > 0 ? @breakdown.values.sum : 0 %>
</span>
<strong>Total</strong>
</li>
</ul>
<%= render 'adsense/banner' %>
</div>
<% end %>
<div class="col-sm-4">
<%= render 'adsense/sidebar' %>
<h3>
<strong>
What's SourceRank used for?
</strong>
</h3>
<p>
SourceRank is the score for a project based on a number of metrics, it's used across the site to boost high quality projects.
</p>
<p>
The factors are based on attributes of a project that make it appear like a dependable library and can be handy to compare different projects.
</p>
<p>
Got a question or suggestion to improve SourceRank? Open an <%= link_to 'issue', 'https://github.com/librariesio/support/issues' %>, <%= link_to 'tweet us', 'https://twitter.com/librariesio' %> or email <%= mail_to 'support@libraries.io', 'support@libraries.io' %>
</p>
</div>
</div>
9 changes: 9 additions & 0 deletions app/workers/update_repository_source_rank_worker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class UpdateRepositorySourceRankWorker
include Sidekiq::Worker
sidekiq_options :queue => :low, unique: :until_executed

def perform(github_repository_id)
repo = GitHubRepository.find_by_id(github_repository_id)
repo.update_source_rank if repo && repo.updated_at.present? && repo.updated_at < 1.day.ago
end
end
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@

get '/github/:owner/:name', to: 'github_repositories#show', as: :github_repository, :defaults => { :format => 'html' }, constraints: { :name => /[\w\.\-\%]+/ }
get '/github/:owner/:name/contributors', to: 'github_repositories#contributors', as: :github_repository_contributors, format: false, constraints: { :name => /[^\/]+/ }
get '/github/:owner/:name/sourcerank', to: 'github_repositories#sourcerank', as: :github_repository_sourcerank, format: false, constraints: { :name => /[^\/]+/ }
get '/github/:owner/:name/forks', to: 'github_repositories#forks', as: :github_repository_forks, format: false, constraints: { :name => /[^\/]+/ }
get '/github/:owner/:name/tags', to: 'github_repositories#tags', as: :github_repository_tags, format: false, constraints: { :name => /[^\/]+/ }
get '/github/:owner/:name/dependency-issues', to: 'github_repositories#dependency_issues', format: false, constraints: { :name => /[^\/]+/ }
Expand Down