Class: Project

Inherits:
ActiveRecord::Base
  • Object
show all
Includes:
Searchable, SourceRank
Defined in:
app/models/project.rb

Constant Summary collapse

HAS_DEPENDENCIES =
false
STATUSES =
['Active', 'Deprecated', 'Unmaintained', 'Help Wanted', 'Removed']
API_FIELDS =
[:name, :platform, :description, :language, :homepage, :repository_url, :normalized_licenses, :rank, :status]

Class Method Summary collapse

Instance Method Summary collapse

Methods included from SourceRank

#all_prereleases?, #any_outdated_dependencies?, #basic_info_present?, #license_present?, #log_scale, #not_brand_new?, #one_point_oh?, #readme_present?, #recent_release?, #repository_present?, #set_source_rank, #source_rank, #source_rank_breakdown, #update_source_rank, #update_source_rank_async, #versions_present?

Class Method Details

.all_languagesObject



280
281
282
# File 'app/models/project.rb', line 280

def self.all_languages
  @all_languages ||= Languages::Language.all.map{|l| l.name.downcase}
end

.facets(options = {}) ⇒ Object



274
275
276
277
278
# File 'app/models/project.rb', line 274

def self.facets(options = {})
  Rails.cache.fetch "facet:#{options.to_s.gsub(/\W/, '')}", :expires_in => 1.hour do
    search('', options).response.facets
  end
end

.format_license(license) ⇒ Object



312
313
314
315
316
# File 'app/models/project.rb', line 312

def self.format_license(license)
  return nil if license.blank?
  return 'Other' if license.downcase == 'other'
  Spdx.find(license).try(:id) || license
end

.keyword(keyword) ⇒ Object



266
267
268
# File 'app/models/project.rb', line 266

def self.keyword(keyword)
  where.contains(keywords_array: [keyword])
end

.keywords_blacklistObject



292
293
294
# File 'app/models/project.rb', line 292

def self.keywords_blacklist
  ['bsd3']
end

.language(language) ⇒ Object



270
271
272
# File 'app/models/project.rb', line 270

def self.language(language)
  where('lower(projects.language) = ?', language.try(:downcase))
end

.license(license) ⇒ Object



262
263
264
# File 'app/models/project.rb', line 262

def self.license(license)
  where.contains(normalized_licenses: [license])
end


304
305
306
# File 'app/models/project.rb', line 304

def self.popular(options = {})
  search('*', options.merge(sort: 'rank', order: 'desc')).records.includes(:github_repository).reject{|p| p.github_repository.nil? }
end


296
297
298
# File 'app/models/project.rb', line 296

def self.popular_keywords(options = {})
  facets(options)[:keywords][:terms].reject{ |t| all_languages.include?(t.term.downcase) }.reject{|t| keywords_blacklist.include?(t.term.downcase) }
end


284
285
286
# File 'app/models/project.rb', line 284

def self.popular_languages(options = {})
  facets(options)[:languages][:terms]
end


300
301
302
# File 'app/models/project.rb', line 300

def self.popular_licenses(options = {})
  facets(options)[:licenses][:terms].reject{ |t| t.term.downcase == 'other' }
end


288
289
290
# File 'app/models/project.rb', line 288

def self.popular_platforms(options = {})
  facets(options)[:platforms][:terms].reject{ |t| t.term.downcase == 'biicode' }
end

.undownloaded_reposObject



258
259
260
# File 'app/models/project.rb', line 258

def self.undownloaded_repos
  with_github_url.without_repo
end

Instance Method Details

#can_have_dependencies?Boolean

Returns:

  • (Boolean)


336
337
338
339
# File 'app/models/project.rb', line 336

def can_have_dependencies?
  return false if platform_class == Project
  platform_class::HAS_DEPENDENCIES
end

#can_have_versions?Boolean

Returns:

  • (Boolean)


341
342
343
344
# File 'app/models/project.rb', line 341

def can_have_versions?
  return false if platform_class == Project
  platform_class::HAS_VERSIONS
end

#colorObject



197
198
199
# File 'app/models/project.rb', line 197

def color
  Languages::Language[language].try(:color) || platform_class.try(:color)
end

#dependent_projects(options = {}) ⇒ Object



245
246
247
248
# File 'app/models/project.rb', line 245

def dependent_projects(options = {})
  options = {per_page: 30, page: 1}.merge(options)
  Project.where(id: dependents.joins(:version).limit(options[:per_page]).offset(options[:per_page]*(options[:page].to_i-1)).pluck('DISTINCT versions.project_id')).order('projects.rank DESC')
end

#descriptionObject



233
234
235
236
237
238
239
# File 'app/models/project.rb', line 233

def description
  if platform == 'Go'
    github_repository.try(:description).presence || read_attribute(:description)
  else
    read_attribute(:description).presence || github_repository.try(:description)
  end
end

#destroy_versionsObject



216
217
218
# File 'app/models/project.rb', line 216

def destroy_versions
  versions.find_each(&:destroy)
end

#first_releaseObject



156
157
158
# File 'app/models/project.rb', line 156

def first_release
  first_version || first_tag
end

#first_tagObject



151
152
153
154
# File 'app/models/project.rb', line 151

def first_tag
  return nil if github_repository.nil?
  github_tags.published.order('published_at ASC').first
end

#first_versionObject



147
148
149
# File 'app/models/project.rb', line 147

def first_version
  @first_version ||= versions.order('published_at ASC').first
end

#follows_semver?Boolean

Returns:

  • (Boolean)


85
86
87
88
89
90
91
# File 'app/models/project.rb', line 85

def follows_semver?
  if versions.all.length > 0
    versions.all?(&:follows_semver?)
  elsif github_tags.published.length > 0
    github_tags.published.all?(&:follows_semver?)
  end
end

#github_name_with_ownerObject



363
364
365
# File 'app/models/project.rb', line 363

def github_name_with_owner
  GithubUrls.parse(repository_url) || GithubUrls.parse(homepage)
end

#github_urlObject



358
359
360
361
# File 'app/models/project.rb', line 358

def github_url
  return nil if repository_url.blank? || github_name_with_owner.blank?
  "https://github.com/#{github_name_with_owner}"
end

#homepageObject



241
242
243
# File 'app/models/project.rb', line 241

def homepage
  read_attribute(:homepage).presence || github_repository.try(:homepage)
end

#is_deprecated?Boolean

Returns:

  • (Boolean)


93
94
95
# File 'app/models/project.rb', line 93

def is_deprecated?
  status == 'Deprecated'
end

#is_removed?Boolean

Returns:

  • (Boolean)


97
98
99
# File 'app/models/project.rb', line 97

def is_removed?
  status == 'Removed'
end

#is_unmaintained?Boolean

Returns:

  • (Boolean)


101
102
103
# File 'app/models/project.rb', line 101

def is_unmaintained?
  status == 'Unmaintained'
end

#keywordsObject



176
177
178
# File 'app/models/project.rb', line 176

def keywords
  keywords_array
end

#latest_releaseObject



143
144
145
# File 'app/models/project.rb', line 143

def latest_release
  latest_version || latest_tag
end

#latest_release_numberObject



172
173
174
# File 'app/models/project.rb', line 172

def latest_release_number
  read_attribute(:latest_release_number) || latest_release.try(:number)
end

#latest_release_published_atObject



160
161
162
# File 'app/models/project.rb', line 160

def latest_release_published_at
  read_attribute(:latest_release_published_at) || (latest_release.try(:published_at).presence || updated_at)
end

#latest_stable_releaseObject



126
127
128
# File 'app/models/project.rb', line 126

def latest_stable_release
  latest_stable_version || latest_stable_tag
end

#latest_stable_release_numberObject



130
131
132
# File 'app/models/project.rb', line 130

def latest_stable_release_number
  latest_stable_release.try(:number)
end

#latest_stable_tagObject



121
122
123
124
# File 'app/models/project.rb', line 121

def latest_stable_tag
  return nil if github_repository.nil?
  github_tags.published.select(&:stable?).sort.first
end

#latest_stable_versionObject



117
118
119
# File 'app/models/project.rb', line 117

def latest_stable_version
  @latest_version ||= stable_releases.sort.first
end

#latest_tagObject



138
139
140
141
# File 'app/models/project.rb', line 138

def latest_tag
  return nil if github_repository.nil?
  github_tags.published.order('published_at DESC').first
end

#latest_versionObject



134
135
136
# File 'app/models/project.rb', line 134

def latest_version
  @latest_version ||= versions.newest_first.sort.first
end

#maintained?Boolean

Returns:

  • (Boolean)


105
106
107
# File 'app/models/project.rb', line 105

def maintained?
  !is_deprecated? && !is_removed? && !is_unmaintained?
end

#mltObject



201
202
203
204
205
206
207
# File 'app/models/project.rb', line 201

def mlt
  begin
    Project.where(id: mlt_ids).limit(5)
  rescue
    []
  end
end

#mlt_idsObject



209
210
211
212
213
214
# File 'app/models/project.rb', line 209

def mlt_ids
  Rails.cache.fetch "projects:#{self.id}:mlt_ids", :expires_in => 1.week do
    results = Project.__elasticsearch__.client.mlt(id: self.id, index: 'projects', type: 'project', mlt_fields: 'keywords_array,platform,description,repository_url', min_term_freq: 1, min_doc_freq: 2)
    ids = results['hits']['hits'].map{|h| h['_id']}
  end
end

#needs_suggestions?Boolean

Returns:

  • (Boolean)


254
255
256
# File 'app/models/project.rb', line 254

def needs_suggestions?
  repository_url.blank? || normalized_licenses.blank?
end

#normalize_licensesObject



318
319
320
321
322
323
324
325
326
327
328
329
330
# File 'app/models/project.rb', line 318

def normalize_licenses
  if licenses.blank?
    normalized = []
  elsif licenses.length > 150
    normalized = ['Other']
  else
    normalized = licenses.split(/[,\/]/).map do |license|
      Spdx.find(license).try(:id)
    end.compact
    normalized = ['Other'] if normalized.empty?
  end
  self.normalized_licenses = normalized
end

#normalized_licensesObject



308
309
310
# File 'app/models/project.rb', line 308

def normalized_licenses
  read_attribute(:normalized_licenses).presence || [Project.format_license(github_repository.try(:license))].compact
end

#ownerObject



184
185
186
187
# File 'app/models/project.rb', line 184

def owner
  return nil unless github_repository
  GithubUser.visible. github_repository.owner_name
end

#package_manager_urlObject



180
181
182
# File 'app/models/project.rb', line 180

def package_manager_url
  Repositories::Base.package_link(self)
end

#platform_classObject



189
190
191
# File 'app/models/project.rb', line 189

def platform_class
  "Repositories::#{platform}".constantize
end

#platform_nameObject



193
194
195
# File 'app/models/project.rb', line 193

def platform_name
  platform_class.formatted_name
end

#prereleasesObject



113
114
115
# File 'app/models/project.rb', line 113

def prereleases
  versions.newest_first.select(&:prerelease?)
end

#release_or_tagObject



346
347
348
# File 'app/models/project.rb', line 346

def release_or_tag
  can_have_versions? ? 'releases' : 'tags'
end

#repo_nameObject



229
230
231
# File 'app/models/project.rb', line 229

def repo_name
  github_repository.try(:full_name)
end

#set_dependents_countObject



250
251
252
# File 'app/models/project.rb', line 250

def set_dependents_count
  self.update_columns(dependents_count: dependents.joins(:version).pluck('DISTINCT versions.project_id').count)
end

#set_languageObject



224
225
226
227
# File 'app/models/project.rb', line 224

def set_language
  return unless github_repository
  self.language = github_repository.try(:language)
end

#set_latest_release_numberObject



168
169
170
# File 'app/models/project.rb', line 168

def set_latest_release_number
  self.latest_release_number = latest_release.try(:number)
end

#set_latest_release_published_atObject



164
165
166
# File 'app/models/project.rb', line 164

def set_latest_release_published_at
  self.latest_release_published_at = (latest_release.try(:published_at).presence || updated_at)
end

#stable_releasesObject



109
110
111
# File 'app/models/project.rb', line 109

def stable_releases
  versions.newest_first.select(&:stable?)
end

#starsObject



220
221
222
# File 'app/models/project.rb', line 220

def stars
  github_repository.try(:stargazers_count) || 0
end

#subscribed_repos(user) ⇒ Object



367
368
369
# File 'app/models/project.rb', line 367

def subscribed_repos(user)
  subscriptions.with_repository_subscription.where('repository_subscriptions.user_id = ?', user.id).map(&:github_repository).uniq
end

#to_paramObject



77
78
79
# File 'app/models/project.rb', line 77

def to_param
  { name: name, platform: platform.downcase }
end

#to_sObject



81
82
83
# File 'app/models/project.rb', line 81

def to_s
  name
end

#update_github_repoObject



350
351
352
353
354
355
356
# File 'app/models/project.rb', line 350

def update_github_repo
  name_with_owner = github_name_with_owner
  return false unless name_with_owner.present?
  g = GithubRepository.create_from_github(name_with_owner)
  return if g.nil?
  self.update_columns(github_repository_id: g.id) unless self.new_record?
end

#update_github_repo_asyncObject



332
333
334
# File 'app/models/project.rb', line 332

def update_github_repo_async
  GithubProjectWorker.perform_async(self.id)
end