diff --git a/Gemfile b/Gemfile index 19527e33d9..b477d972ea 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,7 @@ source "http://rubygems.org" gem 'public_suffix' +gem 'naughty_or_nice' group :development do gem "nokogiri", "~> 1.5" diff --git a/lib/swot.rb b/lib/swot.rb index 7891e8a267..6bd44f881e 100644 --- a/lib/swot.rb +++ b/lib/swot.rb @@ -1,7 +1,8 @@ require "public_suffix" -require File.join(File.dirname(__FILE__), "swot", "academic_tlds.rb") +require "naughty_or_nice" +require_relative "swot/academic_tlds" -module Swot +class Swot < NaughtyOrNice VERSION = "0.3.0" # These are domains that snuck into the edu registry, @@ -13,83 +14,59 @@ module Swot ).freeze class << self + alias_method :is_academic?, :valid? + alias_method :academic?, :valid? - # 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)) + Swot.new(text).institution_name 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) - parts = [File.dirname(__FILE__), "domains"] - parts += domain.domain.split(".").reverse - File.join(*parts) + ".txt" - end - - private - - # http://rubular.com/r/uW2GqSxvqD - def domain_regex - /([^@\/:]+)[:\d]*$/ + def domains_path + @domains_path ||= File.expand_path "domains", File.dirname(__FILE__) end end + + # 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 valid? + if domain.nil? + false + elsif BLACKLIST.any? { |d| domain =~ /(\A|\.)#{Regexp.escape(d)}\z/ } + false + elsif ACADEMIC_TLDS.include?(domain_parts.tld) + true + elsif academic_domain? + true + else + false + end + end + + # Figure out the institution name based on the email address/domain. + # + # Returns a string with the institution name; nil if nothing is found. + def institution_name + @institution_name ||= File.read(file_path, :mode => "rb", :external_encoding => "UTF-8").strip + rescue + nil + end + alias_method :school_name, :institution_name + alias_method :name, :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 academic_domain? + @academic_domain ||= File.exists?(file_path) + end + + private + + def file_path + @file_path ||= File.join(Swot::domains_path, domain_parts.domain.to_s.split(".").reverse) + ".txt" + end end diff --git a/lib/swot/academic_tlds.rb b/lib/swot/academic_tlds.rb index 219edf1975..fea0412fb2 100644 --- a/lib/swot/academic_tlds.rb +++ b/lib/swot/academic_tlds.rb @@ -1,6 +1,6 @@ require 'set' -module Swot +class Swot < NaughtyOrNice # These top-level domains are guaranteed to be academic institutions. ACADEMIC_TLDS = %w( ac.ae