swot/lib/swot.rb
2014-06-18 22:42:30 -04:00

213 lines
3.8 KiB
Ruby

require 'public_suffix'
require 'set'
module Swot
VERSION = "0.3.0"
# These top-level domains are guaranteed to be academic institutions.
ACADEMIC_TLDS = %w(
ac.ae
ac.at
ac.bd
ac.be
ac.cr
ac.cy
ac.fj
ac.id
ac.il
ac.ir
ac.jp
ac.ke
ac.kr
ac.ma
ac.mu
ac.mw
ac.mz
ac.nz
ac.pa
ac.pg
ac.rs
ac.ru
ac.rw
ac.th
ac.tz
ac.ug
ac.uk
ac.yu
ac.za
ac.zm
ac.zw
edu
edu.af
edu.al
edu.ar
edu.au
edu.az
edu.ba
edu.bb
edu.bd
edu.bh
edu.bi
edu.bn
edu.bo
edu.br
edu.bs
edu.bt
edu.bz
edu.co
edu.cu
edu.do
edu.dz
edu.ec
edu.ee
edu.eg
edu.er
edu.es
edu.et
edu.ge
edu.gh
edu.gr
edu.gt
edu.hk
edu.hn
edu.ht
edu.iq
edu.jm
edu.jo
edu.kg
edu.kh
edu.kn
edu.kw
edu.ky
edu.kz
edu.la
edu.lb
edu.lv
edu.ly
edu.mk
edu.mm
edu.mn
edu.mo
edu.mt
edu.mx
edu.my
edu.ni
edu.np
edu.om
edu.pa
edu.pe
edu.ph
edu.pk
edu.pl
edu.pr
edu.ps
edu.pt
edu.py
edu.qa
edu.rs
edu.ru
edu.sa
edu.sd
edu.sg
edu.sv
edu.sy
edu.tr
edu.tt
edu.tw
edu.ua
edu.uy
edu.ve
edu.vn
edu.ws
edu.ye
edu.zm
vic.edu.au
).to_set.freeze
# These are domains that snuck into the edu registry,
# but don't pass the education sniff test
# Note: validated domain must not end with the blacklisted string
BLACKLIST = %w(
si.edu
).freeze
class << self
# Figure out if an email or domain belongs to academic institution.
#
# Returns true if the domain name belongs to an academic institution;
# false otherwise.
def is_academic?(text)
return false if text.nil?
begin
domain = get_domain(text)
if domain.nil?
false
elsif BLACKLIST.any? { |d| domain.name =~ /(\A|\.)#{Regexp.escape(d)}\z/ }
false
elsif ACADEMIC_TLDS.include?(domain.tld)
true
elsif match_academic_domain?(domain)
true
else
false
end
rescue PublicSuffix::DomainInvalid => di
return false
rescue PublicSuffix::DomainNotAllowed => dna
return false
end
end
alias_method :academic?, :is_academic?
# Figure out the institution name based on the email address/domain.
#
# Returns a string with the institution name; nil if nothing is found.
def get_institution_name(text)
name_from_academic_domain(get_domain(text))
end
alias_method :school_name, :get_institution_name
# Figure out if a domain name is a know academic institution.
#
# Returns true if the domain name belongs to a known academic institution;
# false otherwise.
def match_academic_domain?(domain)
File.exists?(get_path(domain)) if domain.tld && domain.sld
end
# Figure out the institutions' name based on the domain name.
#
# Return the institution name, or nil if not found.
def name_from_academic_domain(domain)
begin
File.read(get_path(domain), :mode => "rb", :external_encoding => "UTF-8").strip
rescue
return nil
end
end
# Get the FQDN name from a URL or email address.
#
# Returns a string with the FQDN; nil if there's an error.
def get_domain(text)
PublicSuffix.parse text.strip.downcase.match(domain_regex).captures.first
rescue
return nil
end
def get_path(domain)
File.join(File.dirname(__FILE__), "domains", domain.tld, domain.sld)
end
private
# http://rubular.com/r/uW2GqSxvqD
def domain_regex
/([^@\/:]+)[:\d]*$/
end
end
end