text: # -*- coding: utf-8 -*-
  import sys
  import re
  import os
  
  module_dir = os.path.dirname(__file__)  # get current directory
  
  FREE_PROVIDERS_LIST_FILE = os.path.join(module_dir, "db/free.txt")
  DISPOSABLE_PROVIDERS_LIST_FILE = os.path.join(module_dir, "db/disposable.txt")
  
  free_list = open(FREE_PROVIDERS_LIST_FILE).read().splitlines()
  disposable_list = open(DISPOSABLE_PROVIDERS_LIST_FILE).read().splitlines()
  # All we are really doing is comparing the input string to one
  # gigantic regular expression.  But building that regexp, and
  # ensuring its correctness, is made much easier by assembling it
  # from the "tokens" defined by the RFC.  Each of these tokens is
  # tested in the accompanying unit test file.
  #
  # The section of RFC 2822 from which each pattern component is
  # derived is given in an accompanying comment.
  #
  # (To make things simple, every string below is given as 'raw',
  # even when it's not strictly necessary.  This way we don't forget
  # when it is necessary.)
  #
  WSP = r'[ \t]'                                       # see 2.2.2. Structured Header Field Bodies
  CRLF = r'(?:\r\n)'                                   # see 2.2.3. Long Header Fields
  NO_WS_CTL = r'\x01-\x08\x0b\x0c\x0f-\x1f\x7f'        # see 3.2.1. Primitive Tokens
  QUOTED_PAIR = r'(?:\\.)'                             # see 3.2.2. Quoted characters
  FWS = r'(?:(?:' + WSP + r'*' + CRLF + r')?' + \
        WSP + r'+)'                                    # see 3.2.3. Folding white space and comments
  CTEXT = r'[' + NO_WS_CTL + \
          r'\x21-\x27\x2a-\x5b\x5d-\x7e]'              # see 3.2.3
  CCONTENT = r'(?:' + CTEXT + r'|' + \
             QUOTED_PAIR + r')'                        # see 3.2.3 (NB: The RFC includes COMMENT here
  # as well, but that would be circular.)
  COMMENT = r'\((?:' + FWS + r'?' + CCONTENT + \
            r')*' + FWS + r'?\)'                       # see 3.2.3
  CFWS = r'(?:' + FWS + r'?' + COMMENT + ')*(?:' + \
         FWS + '?' + COMMENT + '|' + FWS + ')'         # see 3.2.3
  ATEXT = r'[\w!#$%&\'\*\+\-/=\?\^`\{\|\}~]'           # see 3.2.4. Atom
  ATOM = CFWS + r'?' + ATEXT + r'+' + CFWS + r'?'      # see 3.2.4
  DOT_ATOM_TEXT = ATEXT + r'+(?:\.' + ATEXT + r'+)*'   # see 3.2.4
  DOT_ATOM = CFWS + r'?' + DOT_ATOM_TEXT + CFWS + r'?' # see 3.2.4
  QTEXT = r'[' + NO_WS_CTL + \
          r'\x21\x23-\x5b\x5d-\x7e]'                   # see 3.2.5. Quoted strings
  QCONTENT = r'(?:' + QTEXT + r'|' + \
             QUOTED_PAIR + r')'                        # see 3.2.5
  QUOTED_STRING = CFWS + r'?' + r'"(?:' + FWS + \
                  r'?' + QCONTENT + r')*' + FWS + \
                  r'?' + r'"' + CFWS + r'?'
  LOCAL_PART = r'(?:' + DOT_ATOM + r'|' + \
               QUOTED_STRING + r')'                    # see 3.4.1. Addr-spec specification
  DTEXT = r'[' + NO_WS_CTL + r'\x21-\x5a\x5e-\x7e]'    # see 3.4.1
  DCONTENT = r'(?:' + DTEXT + r'|' + \
             QUOTED_PAIR + r')'                        # see 3.4.1
  DOMAIN_LITERAL = CFWS + r'?' + r'\[' + \
                   r'(?:' + FWS + r'?' + DCONTENT + \
                   r')*' + FWS + r'?\]' + CFWS + r'?'  # see 3.4.1
  DOMAIN = r'(?:' + DOT_ATOM + r'|' + \
           DOMAIN_LITERAL + r')'                       # see 3.4.1
  ADDR_SPEC = LOCAL_PART + r'@' + DOMAIN               # see 3.4.1
  
  # A valid address will match exactly the 3.4.1 addr-spec.
  VALID_ADDRESS_REGEXP = '^' + ADDR_SPEC + '$'
  
  
  class EmailSegmentClassifier:
      def __init__(self):
          pass
  
      def getHostName(self, email):
          assert re.match(VALID_ADDRESS_REGEXP, email) is not None
          index = email.find('@')
          return email[index + 1:]
  
      def isInList(self, email, list):
          hostname = self.getHostName(email)
          if not hostname:
              raise ValueError
          if hostname in list:
              return True
          else:
              return False
  
      def isFreeEmail(self, email):
          return self.isInList(email, free_list)
  
      def isDisposableEmail(self, email):
          return self.isInList(email, disposable_list)
  
  
  if __name__ == "__main__":
      if(len(sys.argv) > 1):
          email = sys.argv[1]
          segmentP = EmailSegmentClassifier()
          if segmentP.isFreeEmail(email):
              print "Free Email"
          elif segmentP.isDisposableEmail(email):
              print "Disposable Email"
          else:
              print "Unknown Provider"
  