lib/repository.rb
module Repository #:nodoc:
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def acts_as_a_repository(options={})
include Repository::InstanceMethods
end
end
# This module contains instance methods
module InstanceMethods
INTERFACE_METHODS = %w(provider name description repo_type size followers forks forked? languages_with_percentage contributions_of contributions raw_readme)
CONTRIBUTION_COUNT_THRESHOLD = 10
CONTRIBUTION_PERCENT_THRESHOLD = 0.10
ACCEPTABLE_LANGUAGE_THRESHOLD = 1.0
LANGUAGE_THRESHOLD_FOR_README = 10.0
MINIMUM_REPOSITORY_SIZE = 3*1024
DISABLE = nil
REPOSITORY_TYPES = %w(personal org)
PROJECT_TYPES = {
'JQuery' => {matcher: /jquery/i,
readme_matcher: DISABLE,
language: 'JavaScript'},
'Node' => {matcher: /(node.js|no.de|nodejs|(\s|\A|^)node(\s|\A|-|_|^))/i,
readme_matcher: DISABLE,
language: 'JavaScript'},
'Prototype' => {matcher: /prototype/i,
readme_matcher: DISABLE,
language: 'JavaScript'},
'Django' => {matcher: /django/i,
readme_matcher: DISABLE,
language: 'Python'}
}
INTERFACE_METHODS.each do |method|
define_method(method) { raise NotImplementedError.new("You must implement #{method} method") }
end
attr_accessor :tags
def initialize
@tags = []
end
def significant?
size >= MINIMUM_REPOSITORY_SIZE
end
def languages
languages_with_percentage.keys
end
#Languages
def dominant_language
return '' if languages.blank?
primary_language = languages_with_percentage.sort_by { |k, v| v }.last
if primary_language
primary_language.first
else
''
end
end
def languages_that_meet_threshold
languages_with_percentage.collect do |key, value|
key if value.to_i >= ACCEPTABLE_LANGUAGE_THRESHOLD
end.compact
end
def dominant_language_percentage
main_language = self.dominant_language
bytes_of_other_langs = languages_with_percentage.collect { |k, v| k != main_language ? v : 0 }.sum
bytes_of_main_lang = languages_with_percentage[main_language]
return 0 if bytes_of_main_lang == 0
return 100 if bytes_of_other_langs == 0
100 - (bytes_of_other_langs.quo(bytes_of_main_lang).to_f * 100).round
end
#Contributions
def percentage_contributions_of(user_credentials)
contributions_of(user_credentials) / contributions.to_f
end
def significant_contributor_to?(repo_credentials)
contributions_of(user_credentials) >= CONTRIBUTION_COUNT_THRESHOLD || percentage_contributions_of(repo_credentials) > CONTRIBUTION_PERCENT_THRESHOLD
end
#Repo Status
def popularity
@popularity ||= begin
rank = forks + watchers
case
when rank > 600 then
5
when rank > 300 then
4
when rank > 100 then
3
when rank > 20 then
2
else
1
end
end
end
def original?
!forked?
end
def has_contents?
!languages_that_meet_threshold.blank?
end
def readme
@readme ||= raw_readme
end
#tags and tagging
def update_tags!
tag_dominant_lanugage!
tag_project_types!
tag_repo!
@tags.uniq!
end
def tag_dominant_lanugage!
@tags << dominant_language unless languages.blank?
end
def tag_project_types!
PROJECT_TYPES.each do |type, project|
return true if tag_when_project_matches(type, project[:matcher], project[:readme_matcher], project[:language])
end
false
end
def tag_repo!
@tags += ['repo', provider, name, repo_type]
@tags << (forked? ? 'fork' : 'original')
end
def add_tag(tag)
@tags << tag
end
def tagged?(tag)
tags.include?(tag)
end
def tag_when_project_matches(tag_name, matcher, readme_matcher, language = nil)
if language && dominant_language.downcase == language.downcase
if field_matches?(self.name, matcher) ||
field_matches?(self.description, matcher) ||
(readme_matcher && dominant_language_percentage > LANGUAGE_THRESHOLD_FOR_README && readme_matches?(readme_matcher))
@tags << tag_name
return true
end
end
return false
end
def field_matches?(field, regex)
!field.match(regex).nil?
end
def readme_matches?(regex)
!readme.match(regex).nil?
end
end
end