require "rubygems" require "prawn" require "prawn/measurement_extensions" require "util.rb" class NSFConflicts include Text ## The NSF considers collaborators from within the past 48 months ## Be conservative and add a few extra days in ## Track this in seconds (because time deltas are given in seconds) @@time_to_consider_collabs = 60*60*24*365.25*2 def initialize(me, data) @me = me @data = data @meta = @data["people"]. merge( @data["lab/members"]. map { |k,m| [k, { "institution" => "University at Buffalo", "email" => "#{m["ubit"]}@buffalo.edu" }.merge(m)] }.to_h ).merge( @data["lab/alumni"]. map { |k,m| [k, { "name" => k, "institution" => m["company"], "email" => "#{m["ubit"]}@buffalo.edu" }.merge(m)] }.to_h ) @shortname = full_details(@me)["ubit"] @my_data = @data["cv"][@shortname] end def grant_co_pis @data["cv/okennedy/grants"]. where { |grant| case grant["status"] when "accepted", "submitted", "completed" then true when "rejected", "retired" then false else raise "Unknown grant status #{grant["status"]} for #{grant["title"]}" end }. where { |grant| Time.now - to_date(grant["end"]) < @@time_to_consider_collabs }. map do |grant| co_pis = grant.fetch("copis", []) grant.fetch("collaborative", []).each do |inst| co_pis = co_pis + inst["pis"] end last_active = to_date(grant["end"]) last_active = Time.now if last_active > Time.now co_pis.flatten.map { |name| [name, "#{last_active.year}-#{last_active.month}-#{last_active.day}"] } end. flatten(1) end def paper_coauthors start_year = (Time.now - @@time_to_consider_collabs).year @data["publications"]. where { |paper| paper["authors"].include? @me }. where { |paper| paper["year"].to_i >= start_year }. map { |paper| paper["authors"]. where { |name| name != @me }. map { |name| [name, "#{paper["year"].to_i}-01-01"] } }. flatten(1) end def advisors @data["cv/#{@shortname}/education"] .where { |inst| inst["degree"] == "PhD" } .map { |inst| inst["Advisor"] } end def committee @data["cv/#{@shortname}/education"] .where { |inst| inst["degree"] == "PhD" } .map { |inst| inst["Committee"] } .flatten(1) end def phd_students @data["lab/members"] .values .where { |person| person["status"] == "PhD" } .map { |person| person["name"] } end def phd_alumni @data["lab/alumni"] .values .where { |person| person["degree"] == "PhD" } .map { |person| person["name"] } end def canonicalize(person) @meta.fetch(person, {"canonical" => person}) .fetch("canonical", person) end def full_details(person) return person.map { |x| full_details(x) } if person.is_a? Array meta = @meta[person] or raise "Unknown Person: #{person}" { "name" => person, "name_parts" => split_name(person) }.merge(meta) end def render_name(person) person["name_parts"].reverse.join(", ") end def render(target) all_collabs = ( (grant_co_pis + paper_coauthors).map { |x| x[0] } + (phd_students + phd_alumni + advisors + committee) ).uniq.sort missing_collabs = all_collabs.select { |person| not (@meta.has_key? person) } unless missing_collabs.empty? puts ("You are missing collaborator details. Here's a template to add to /db/people.json:") missing_collabs.each do |collab| puts " \"#{collab}\" : {" puts " \"institution\" : \"\"," puts " \"updated\" : \"#{Time.now.year}\"" puts " }," end end File.open(target, "w+") do |f| f.puts("==== TABLE A ====") f.puts("\t#{@my_data["name"]}\t#{@my_data["work"]["employer"]}") f.puts("==== TABLE B ====") full_details(advisors).each do |adv| f.puts "G:\t#{render_name(adv)}\t#{adv["institution"]}\t#{adv["email"]}" end full_details((committee + phd_students + phd_alumni).uniq.sort).each do |stud| f.puts "T:\t#{render_name(stud)}\t#{stud["institution"]}\t#{stud["email"]}" end f.puts("==== TABLE C ====") all_collabs = ( grant_co_pis.map { |name, y| [canonicalize(name), [:grant, y]] } + paper_coauthors.map { |name, y| [canonicalize(name), [:pub, y]] } ) all_collabs .my_reduce .to_a .sort_by { |name, collabs| render_name(full_details(name)) } .each { |name, collabs| categories, years = collabs.unzip category = "C:" category = "A:" if(categories.include? :pub) details = full_details(name) f.puts("#{category}\t#{render_name(details)}\t#{details["institution"]}\t#{details["email"]}\t#{years.max}") } end end end