Website/lib/lab_metadata.rb

384 lines
11 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.pubmed_abbreviation(name)
n = name.split(/ +/)
last = n.pop
last + " " + n.map { |n| n[0] }.join("")
end
def LabMetadata.ris_for(pub)
fields = []
venue = LabMetadata.complete_venue(pub)
fields.push(["TY",
case venue["type"]
when "journal" then "JOUR"
when "conference", "workshop", "abstract" then "CONF"
when "thesis" then "THES"
when "techreport" then "RPRT"
when "chapter" then "CHAP"
when "patent" then "PAT"
else raise "Unknown pub type for RIS: '#{venue["type"]}' (in #{pub["title"]})"
end
])
pub["authors"].each do |au|
au = au.split(" ")
last = au.pop
first = au.shift
first = ([first] + au.map { |n| n[0]+"." }).join(" ")
fields.push(["AU",
"#{last}, #{first}"
])
end
fields.push(["PY", venue["year"].to_s])
fields.push(["TI", pub["title"]])
fields.push(["T2", venue["fullname"]])
if venue["type"] == "journal" then
if pub.include? "pages"
pages = pub["pages"].split("-+")
fields.push(["SP", pages[0]])
fields.push(["EP", if pages.size > 1 then pages[1] else pages[0] end])
end
fields.push(["VL", pub["volume"].to_s])
end
fields.push(["ER", ""])
fields.map { |tag,value| "#{tag} - #{value}" }.join("\n")
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