Website/lib/lab_metadata.rb
Oliver Kennedy 0268dc0179 Book chapter
2019-06-28 18:21:07 -04:00

340 lines
10 KiB
Ruby

module LabMetadata
@@cnames = {}
def LabMetadata.build_people_metadata
$db["lab/members"].each do |name, data|
data["link_relative"] = not(data.has_key? "link")
data["name"] = name
unless data.has_key? "shortname"
data["shortname"] =
name.
downcase.
gsub(/ /, "_").
gsub(/[^a-z0-9A-Z_]/, "")
end
@@cnames[name] = name
@@cnames[data["shortname"]] = name
@@cnames[data["ubit"]] = name if data.has_key? "ubit"
page = "/people/#{data["shortname"]}.html"
unless data.has_key? "link"
data["link"] = page
end
data["page"] = page
end
$db["lab/alumni"].each do |name, data|
data["name"] = name
@@cnames[name] = name
@@cnames[data["shortname"]] = name
@@cnames[data["ubit"]] = name if data.has_key? "ubit"
end
end
def LabMetadata.is_member?(name)
$db["lab/members"].has_key? name or $db["lab/alumni"].has_key? name
end
def LabMetadata.create_people_pages
known_pages =
GemSmith::all_outputs.
delete_if { |x| not /people\/.*\.html$/ =~ x }
$db["lab/members"].each do |name, data|
unless known_pages.include? data["page"]
GemSmith::add_file_string(data["page"], "#{name} hasn't written anything about themselves yet.")
end
GemSmith::metadata_for(data["page"]).merge!({
title: name,
name: name
}.merge(data))
end
end
def LabMetadata.project_link(project)
data = $db["lab/projects"].fetch(project, {})
url = data.fetch("url", "/research/#{project}")
name = data.fetch("name", project.gsub(/[_-]/, " ").capitalize)
return "<a href=\"#{url}\">#{name}</a>"
end
def LabMetadata.data_for(person)
cname = @@cnames[person] || person
data = $db["lab/members"][cname]
if data.nil?
data = $db["people"][cname]
end
data
end
def LabMetadata.link_for(person)
cname = @@cnames[person] || person
data = $db["lab/members"][cname]
unless data.nil? then
link =
if /^https?:\/\// =~ data["link"] then data["link"]
else GemSmith::root_path(data["link"]) end
"<a class=\"lab_member\" href=\"#{link}\">#{person}</a>"
else
alum = $db["lab/alumni/#{cname}"]
if alum and alum["link"] then
"<a class=\"lab_member\" href=\"#{alum["link"]}\">#{person}</a>"
elsif alum then
"<span class=\"lab_member\">#{person}</span>"
else
person
end
end
end
def LabMetadata.publications_for(person)
cname = @@cnames[person]
raise "Unknown person '#{person}'" if cname.nil?
$db["publications"].
where { |pub| pub["authors"].include? cname }
end
def LabMetadata.shortname_for(publication)
venue = LabMetadata.complete_venue(publication)
publication.fetch("shortname", [
publication["authors"][0].split(/ +/)[-1].downcase,
publication["year"],
publication["venue"].nil? ? nil : publication["venue"].downcase.gsub(/[^a-zA-Z0-9\-]/, ""),
publication["title"].split(/ +/).
map {|x| x.downcase.gsub(/[^a-zA-Z0-9\-]/, "") }.
delete_if {|x| ["the", "a"].include? x }[0]
].compact.join(":")
)
end
def LabMetadata.bibtex_for(publication)
venue = LabMetadata.complete_venue(publication)
authors = publication["authors"].
map { |author|
author = author.split(/ +/)
last = author.pop
"#{last}, #{author.join(" ")}"
}
type, meta =
case venue["type"]
when "workshop", "conference", "demo"
[ "inproceedings",
{
author: authors.join(" and "),
title: publication["title"],
booktitle: LabMetadata.venue_name(venue, size: :short),
year: publication["year"]
}
]
when "chapter", "book"
[
"incollection",
{
author: authors.join(" and "),
title: publication["title"],
editor: publication["editor"],
booktitle: publication["booktitle"],
publisher: venue["publisher"],
year: publication["year"],
pages: publication["pages"]
}
]
when "journal"
[ "article",
{
author: authors.join(" and "),
title: publication["title"],
journal: LabMetadata.venue_name(venue, size: :short),
volume: publication["volume"],
number: publication["number"],
year: publication["year"],
month: publication["month"],
pages: publication["pages"]
}
]
when "techreport"
[ "techreport",
{
author: authors.join(" and "),
title: publication["title"],
institution: LabMetadata.venue_name(venue, size: :short),
year: publication["year"]
}
]
when "patent", "panel"
[ "misc",
{
title: publication["title"],
author: authors.join(" and "),
year: publication["year"]
}
]
when "thesis"
[
"#{venue["degree"].downcase}thesis",
{
author: authors.join(" and "),
title: publication["title"],
school: venue["school"],
year: publication["year"]
}
]
when "abstract"
[ "misc",
{
author: authors.join(" and "),
title: publication["title"],
howpublished: LabMetadata.venue_name(venue, size: :short),
year: publication["year"]
}
]
else
raise "Unknown venue type '#{venue["type"]}' for publication '#{publication["title"]}'"
end
"@#{type}{#{LabMetadata.shortname_for(publication)},"+(
meta.delete_if { |k,v| v.nil? }.
map { |k,v| "\n #{k} = {#{v}}" }.
join(",")
)+"\n}"
end
def LabMetadata.members_on_project(project, role = /.*/)
role = case role
when :student then /PhD|BS|MS/
else role
end
$db["lab/members"].values
.where { |m| m.fetch("projects", []).include? project }
.select { |m| role =~ m.fetch("status", "") }
.map { |m| m["name"] }
end
def LabMetadata.alumni_on_project(project)
$db["lab/alumni"].values.
where { |m| m.fetch("projects", []).include? project }.
map { |m| m["name"] }
end
def LabMetadata.complete_venue(record)
v = record["venue"];
t = record["track"];
y = record["year"]
v = $db["venues"][v];
## if there is no additional metadata for the venue, we're done.
return record if v.nil?;
## if there's no request for a subtrack or year, merge with what we have.
result =
if t.nil? then v.clone.merge record
else
tracks = v["tracks"]
if tracks.nil? then record
elsif tracks[t].nil? then record
else tracks[t].clone.merge record
end
end
if result.has_key? "years" and not y.nil? and result["years"].has_key? y.to_s
result = result.merge result["years"][y.to_s]
end
return result
end
def LabMetadata.venue_name(record, args = {})
v = LabMetadata.complete_venue(record)
short = v["acronym"] || v["venue"]
raise "Unknown venue: #{short}" if v.nil?
raise "Unknown abbreviation: #{v}" if short.nil?
case args.fetch(:size, :full_parens)
when :full_parens then "#{v["fullname"]} (#{short})"
when :full then v["fullname"]
when :short then short
end
end
def LabMetadata.venue_selectivity(record, params = {})
rounding = params.fetch(:rounding, 2)
year = record["year"].to_s
v = LabMetadata.complete_venue(record)
sel_data = v["selectivity"]
if sel_data.nil?
"unavailable"
elsif sel_data["average"].is_a? Numeric
"approximately #{(sel_data["average"]*100).round(rounding)}%"
elsif not sel_data["average"].nil?
sel_data["average"]
else
"approximately #{
(sel_data.keys.
delete_if { |k| /a-zA-Z/ =~ k }.
map { |k| sel_data[k].to_f }.
avg * 100).round(rounding)
}%"
end
end
def LabMetadata.abbreviate_person(name)
n = name.split(/ +/)
last = n.pop
(n.map { |n| "#{n[0]}." } + [last]).join(" ")
end
def LabMetadata.person_name(full, args = {})
person = LabMetadata.data_for(full)
person = {} if person.nil?
case args.fetch(:size, :short)
when :full then person["full"] or full
when :short then person["short"] or abbreviate_person(full)
when :last then person["last"] or full.split(/ +/).pop
end
end
@@publication_erb = File.open("lib/publication.erb"){ |f| ERB.new(f.readlines.join) }
def LabMetadata.render_pub(pub)
b = binding()
b.local_variable_set(:pub, pub)
@@publication_erb.result(b)
end
def LabMetadata.render_pubs(publist)
"<dl>\n"+publist.map { |pub| render_pub(pub) }.join("\n")+"\n</dt>"
end
def LabMetadata.info_for_affiliate(name)
info = { "canonical" => name }
while(info.include? "canonical")
name = info["canonical"]
info = $db["people"][name] or raise "Unknown Collaborator: #{name}"
end
return { "name" => name }.merge(info)
end
def LabMetadata.format_pub_for_report(pub)
pub = LabMetadata::complete_venue(pub)
pub =
case pub["type"]
when "conference", "journal", "workshop", "abstract" then
[ pub["title"],
pub["authors"].join(", "),
"#{LabMetadata::venue_name(pub, size: :full_parens)} #{pub["year"]}",
pub["urls"].map { |k,v| "#{k.capitalize}: #{v}" },
LabMetadata.bibtex_for(pub).split("\n")
].flatten
when "thesis" then
[ pub["title"],
pub["authors"].join(", "),
"Thesis #{pub["degree"]} #{pub["year"]}",
pub.fetch("urls", []).map { |k,v| "#{k.capitalize}: #{v}" },
LabMetadata.bibtex_for(pub).split("\n")
].flatten
else nil
end
pub = "> " + pub.join("\n ") unless pub.nil?
return pub
end
end