src/api/app/models/project_status/calculator.rb
module ProjectStatus
class Calculator
def initialize(dbproj)
@dbproj = dbproj
end
def calc_status(opts = {})
return {} unless @dbproj
mypackages = {}
@dbproj.packages.select(%i[id name project_id develpackage_id]).includes(:develpackage, :backend_package).load.each do |dbpack|
add_recursively(mypackages, dbpack)
end
projects = {}
get_list_of_project_and_packages(mypackages.keys).each do |project_id, project_name, package_name|
package_info = mypackages[package_name]
package_info.project = project_name
package_info.links_to = mypackages[package_info.links_to_id] if package_info.links_to_id
projects[project_id] = project_name
end
selected_projects = projects.keys.select { |project_id| !opts[:pure_project] || project_id == @dbproj.id }
selected_projects.each { |project_id| update_jobhistory(Project.find(project_id), mypackages) }
# cleanup
mypackages.each_key do |key|
mypackages.delete(key) if mypackages[key].project != @dbproj.name
end
mypackages
end
private
# parse the jobhistory and put the result in a format we can cache
def parse_jobhistory(dname, repo, arch)
data = Xmlhash.parse(Backend::Api::BuildResults::Binaries.job_history(dname, repo, arch))
return [] if data.blank?
data.elements('jobhist').collect do |p|
{
'name' => p['package'],
'code' => p['code'],
'versrel' => p['versrel'],
'verifymd5' => p['verifymd5'],
'readytime' => p.key?('readytime') ? p['readytime'].to_i : 0
}
end
end
def add_recursively(mypackages, dbpack)
return if mypackages.key?(dbpack.id)
pack = PackInfo.new(dbpack)
pack.backend_package = dbpack.backend_package
if dbpack.develpackage
add_recursively(mypackages, dbpack.develpackage)
pack.develpack = mypackages[dbpack.develpackage_id]
end
mypackages[pack.package_id] = pack
end
def get_list_of_project_and_packages(ids)
Project.joins(:packages).where(packages: { id: ids }).pluck('projects.id, projects.name, packages.id')
end
def update_jobhistory(proj, mypackages)
prjpacks = {}
dname = proj.name
mypackages.each_value do |package|
prjpacks[package.name] = package if package.project == dname
end
proj.repositories_linking_project(@dbproj).each do |r|
repo = r['name']
r.elements('arch') do |arch|
cachekey = "history2#{proj.cache_key_with_version}#{repo}#{arch}"
jobhistory = Rails.cache.fetch(cachekey, expires_in: 30.minutes) do
parse_jobhistory(dname, repo, arch)
end
jobhistory.each do |p|
pkg = prjpacks[p['name']]
next unless pkg
pkg.set_versrel(p['versrel'], p['readytime'])
pkg.failure(repo, arch, p['readytime'], p['verifymd5']) if p['code'] == 'failed'
end
end
end
end
end
end