home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 October / maximum-cd-2011-10.iso / DiscContents / digsby_setup.exe / lib / mail / smtp.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2011-06-22  |  11.6 KB  |  356 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. import traceback
  5. from common import profile
  6. from util import unpack_pstr, pack_pstr
  7. from common.emailaccount import EmailAccount, localprefs_key
  8. from AccountManager import NETWORK_FLAG
  9. from prefs import localprefprop
  10. SMTP_UPGRADING = True
  11. import smtplib
  12. import re
  13. import logging
  14. log = logging.getLogger('smtp')
  15. MAXHEADERLEN = 76
  16.  
  17. class SMTPsender(object):
  18.     _ignore_domains = []
  19.     addrfmt = '[\\w\\d_\\.\\-\\+=]+\\@(?:(?:[\\w\\d\\-])+\\.)+(?:[\\w\\d]{2,4})'
  20.     shortaddr_re = re.compile('%s$' % addrfmt)
  21.     longaddr_re = re.compile('^\\s*(.*)\\s+<(%s)>\\s*$' % addrfmt)
  22.     
  23.     def __init__(self, name, password, server, port = 25, use_tls = False, from_name = None, reply_to = None):
  24.         self.user_name = name
  25.         self.password = password
  26.         self.smtp_server = server
  27.         self.smtp_port = port
  28.         self.from_name = None if from_name is not None else name
  29.         self.replyto_email = None if reply_to is not None else name
  30.         self._use_tls = use_tls
  31.         self._init_pref_encoding()
  32.  
  33.     
  34.     def format_header(self, key, name, email = None):
  35.         Header = Header
  36.         import email.Header
  37.         maxlength = MAXHEADERLEN - (len(key) + 2)
  38.         if maxlength < 10:
  39.             raise AssertionError, 'Header length is too short'
  40.         maxlength < 10
  41.         
  42.         try:
  43.             tmp = None if isinstance(name, unicode) else name
  44.             header = Header(tmp, 'utf-8', maxlinelen = maxlength)
  45.         except UnicodeEncodeError:
  46.             header = Header(name, self._charset, maxlinelen = maxlength)
  47.  
  48.         if not email:
  49.             return header
  50.         return '"%s" <%s>' % (header, email)
  51.  
  52.     
  53.     def add_headers(self, msg, headers):
  54.         for h in headers:
  55.             msg[h] = self.encode_header(h, headers[h])
  56.         
  57.  
  58.     
  59.     def get_smtp_address(self, address):
  60.         if not address:
  61.             return None
  62.         
  63.         def is_email(address):
  64.             pos = address.find('@')
  65.             if pos == -1:
  66.                 return False
  67.             if address[pos + 1:].lower() in self._ignore_domains:
  68.                 return False
  69.             return True
  70.  
  71.         mo = self.shortaddr_re.search(address)
  72.         if mo:
  73.             return mo.group(0)
  74.         mo = self.longaddr_re.search(address)
  75.         if mo:
  76.             return mo.group(2)
  77.         self.env.log.info('Invalid email address: %s' % address)
  78.  
  79.     
  80.     def _init_pref_encoding(self):
  81.         Charset = Charset
  82.         QP = QP
  83.         BASE64 = BASE64
  84.         import email.Charset
  85.         self._charset = Charset()
  86.         self._charset.input_charset = 'utf-8'
  87.         pref = 'base64'
  88.         if pref == 'base64':
  89.             self._charset.header_encoding = BASE64
  90.             self._charset.body_encoding = BASE64
  91.             self._charset.output_charset = 'utf-8'
  92.             self._charset.input_codec = 'utf-8'
  93.             self._charset.output_codec = 'utf-8'
  94.         elif pref in ('qp', 'quoted-printable'):
  95.             self._charset.header_encoding = QP
  96.             self._charset.body_encoding = QP
  97.             self._charset.output_charset = 'utf-8'
  98.             self._charset.input_codec = 'utf-8'
  99.             self._charset.output_codec = 'utf-8'
  100.         elif pref == 'none':
  101.             self._charset.header_encoding = None
  102.             self._charset.body_encoding = None
  103.             self._charset.input_codec = None
  104.             self._charset.output_charset = 'ascii'
  105.         else:
  106.             raise AssertionError, 'Invalid email encoding setting: %s' % pref
  107.         return pref == 'base64'
  108.  
  109.     
  110.     def encode_header(self, key, value):
  111.         if isinstance(value, tuple):
  112.             return self.format_header(key, value[0], value[1])
  113.         if isinstance(value, list):
  114.             items = []
  115.             for v in value:
  116.                 items.append(self.encode_header(v))
  117.             
  118.             return ',\n\t'.join(items)
  119.         mo = self.longaddr_re.match(value)
  120.         if mo:
  121.             return self.format_header(key, mo.group(1), mo.group(2))
  122.         return self.format_header(key, value)
  123.  
  124.     
  125.     def begin_send(self):
  126.         self.server = smtplib.SMTP(self.smtp_server, self.smtp_port)
  127.         if self._use_tls:
  128.             self.server.ehlo()
  129.             if not self.server.esmtp_features.has_key('starttls'):
  130.                 raise AssertionError, 'TLS enabled but server does not support TLS'
  131.             self.server.esmtp_features.has_key('starttls')
  132.             self.server.starttls()
  133.             self.server.ehlo()
  134.         
  135.         if self.user_name:
  136.             
  137.             try:
  138.                 self.server.login(self.user_name, self.password)
  139.  
  140.         
  141.  
  142.     
  143.     def send_email(self, to = '', subject = '', body = '', cc = '', bcc = ''):
  144.         self.begin_send()
  145.         self.send([
  146.             to], [], subject, body)
  147.         
  148.         try:
  149.             self.finish_send()
  150.         except:
  151.             pass
  152.  
  153.  
  154.     
  155.     def send(self, torcpts, ccrcpts, subject, body, mime_headers = { }):
  156.         MIMEText = MIMEText
  157.         import email.MIMEText
  158.         headers = { }
  159.         headers['Subject'] = subject
  160.         headers['From'] = (self.from_name, self.from_name)
  161.         
  162.         def build_addresses(rcpts):
  163.             return []([], [ self.get_smtp_address(addr) for addr in rcpts ])
  164.  
  165.         
  166.         def remove_dup(rcpts, all):
  167.             tmp = []
  168.             for rcpt in rcpts:
  169.                 if rcpt not in all:
  170.                     tmp.append(rcpt)
  171.                     all.append(rcpt)
  172.                     continue
  173.             
  174.             return (tmp, all)
  175.  
  176.         toaddrs = build_addresses(torcpts)
  177.         recipients = []
  178.         (toaddrs, recipients) = remove_dup(toaddrs, recipients)
  179.         if len(recipients) < 1:
  180.             return None
  181.         headers['To'] = ', '.join(toaddrs)
  182.         msg = MIMEText(body.encode('utf-8'), 'plain')
  183.         del msg['Content-Transfer-Encoding']
  184.         msg.set_charset(self._charset)
  185.         self.add_headers(msg, headers)
  186.         self.add_headers(msg, mime_headers)
  187.         msgtext = msg.as_string()
  188.         recrlf = re.compile('\r?\n')
  189.         msgtext = '\r\n'.join(recrlf.split(msgtext))
  190.         self.server.sendmail(msg['From'], recipients, msgtext)
  191.  
  192.     
  193.     def finish_send(self):
  194.         if self._use_tls:
  195.             import ssl
  196.             
  197.             try:
  198.                 self.server.quit()
  199.             except ssl.SSLError:
  200.                 pass
  201.             except:
  202.                 None<EXCEPTION MATCH>ssl.SSLError
  203.             
  204.  
  205.         None<EXCEPTION MATCH>ssl.SSLError
  206.         self.server.quit()
  207.  
  208.  
  209. from common.emailaccount import EmailAccount
  210. from util import threaded
  211.  
  212. class SMTPEmailAccount(EmailAccount):
  213.     DEFAULT_SMTP_REQUIRE_SSL = False
  214.     DEFAULT_SMTP_PORT = 25
  215.     
  216.     def __init__(self, **options):
  217.         d = self.default
  218.         self.smtp_server = options.get('smtp_server', d('smtp_server'))
  219.         self.smtp_require_ssl = options.get('smtp_require_ssl', d('smtp_require_ssl'))
  220.         self.smtp_port = options.get('smtp_port', d('smtp_port'))
  221.         self.smtp_username = options.get('smtp_username', d('smtp_username'))
  222.         self._email_address = options.get('email_address', d('email_address'))
  223.         self._encrypted_smtppw = profile.crypt_pw(options.get('smtp_password', d('smtp_password')))
  224.         self._encrypted_pw = options.pop('password')
  225.         EmailAccount.__init__(self, password = self.password, **options)
  226.  
  227.     
  228.     def get_email_address(self):
  229.         return self._email_address
  230.  
  231.     
  232.     def set_email_address(self, val):
  233.         self._email_address = val
  234.  
  235.     
  236.     def from_name(self):
  237.         return self.email_address
  238.  
  239.     from_name = property(from_name)
  240.     
  241.     def _unglue_pw(cls, password):
  242.         passwordstr = profile.plain_pw(password).encode('utf-8')
  243.         if passwordstr:
  244.             (password, r) = unpack_pstr(passwordstr)
  245.             
  246.             try:
  247.                 (smtppassword, r) = unpack_pstr(r)
  248.             except Exception:
  249.                 (smtppassword, r) = ('', '')
  250.             except:
  251.                 None<EXCEPTION MATCH>Exception
  252.             
  253.  
  254.         None<EXCEPTION MATCH>Exception
  255.         raise ValueError("Can't decrypt %r", password)
  256.         return (profile.crypt_pw(password.decode('utf-8')), profile.crypt_pw(smtppassword.decode('utf-8')))
  257.  
  258.     _unglue_pw = classmethod(_unglue_pw)
  259.     
  260.     def _set_password(self, password):
  261.         
  262.         try:
  263.             (self._encrypted_pw, self._encrypted_smtppw) = self._unglue_pw(password)
  264.         except Exception:
  265.             e = None
  266.             traceback.print_exc()
  267.             self._encrypted_pw = password
  268.  
  269.  
  270.     
  271.     def _glue_pw(cls, encrypted_pw, encrypted_smtppw):
  272.         password = pack_pstr(profile.plain_pw(encrypted_pw).encode('utf-8')).decode('utf-8')
  273.         smtppw = pack_pstr(profile.plain_pw(encrypted_smtppw).encode('utf-8')).decode('utf-8')
  274.         return profile.crypt_pw(password + smtppw)
  275.  
  276.     _glue_pw = classmethod(_glue_pw)
  277.     
  278.     def _get_password(self):
  279.         return self._glue_pw(self._encrypted_pw, self._encrypted_smtppw)
  280.  
  281.     password = property(_get_password, _set_password)
  282.     
  283.     def _decryptedpw(self):
  284.         return profile.plain_pw(self._encrypted_pw)
  285.  
  286.     
  287.     def _decrypted_smtppw(self):
  288.         return profile.plain_pw(self._encrypted_smtppw)
  289.  
  290.     smtp_password = property(_decrypted_smtppw)
  291.     
  292.     def update_info(self, **info):
  293.         if not self.isflagged(NETWORK_FLAG):
  294.             if 'smtp_password' in info:
  295.                 self._encrypted_smtppw = profile.crypt_pw(info.pop('smtp_password'))
  296.                 if 'password' in info:
  297.                     self._encrypted_pw = info['password']
  298.                 
  299.             
  300.             if '_encrypted_pw' in info and '_encrypted_smtppw' in info:
  301.                 self._encrypted_pw = info.pop('_encrypted_pw')
  302.                 self._encrypted_smtppw = info.pop('_encrypted_smtppw')
  303.             
  304.             info['password'] = self._glue_pw(self._encrypted_pw, self._encrypted_smtppw)
  305.         else:
  306.             self.password = info.pop('password')
  307.         log.info('smtp update_info: %r', info)
  308.         EmailAccount.update_info(self, **info)
  309.  
  310.     
  311.     def _get_options(self):
  312.         opts = EmailAccount._get_options(self)
  313.         opts.update((dict,)((lambda .0: for a in .0:
  314. (a, getattr(self, a)))('smtp_server smtp_port smtp_require_ssl smtp_username email_address'.split())))
  315.         return opts
  316.  
  317.     
  318.     def from_net(cls, info):
  319.         password = info.password
  320.         
  321.         try:
  322.             (encrypted_pw, encrypted_smtppw) = cls._unglue_pw(password)
  323.         except Exception:
  324.             e = None
  325.             traceback.print_exc()
  326.             encrypted_pw = password
  327.             encrypted_smtppw = u''
  328.  
  329.         info.password = encrypted_pw
  330.         smtppw = profile.plain_pw(encrypted_smtppw)
  331.         return EmailAccount.from_net(info, smtp_password = smtppw)
  332.  
  333.     from_net = classmethod(from_net)
  334.     
  335.     def send_email(self, to = '', subject = '', body = '', cc = '', bcc = ''):
  336.         if not self.smtp_username:
  337.             pass
  338.         un = self.username
  339.         f = self.from_name
  340.         if not self._decrypted_smtppw():
  341.             pass
  342.         password = None if not self.smtp_username else ''
  343.         srv = self.smtp_server
  344.         if srv in ('smtp.aol.com', 'smtp.aim.com'):
  345.             if un.endswith('aol.com') or un.endswith('aim.com'):
  346.                 f = un
  347.             else:
  348.                 f = un + u'@aol.com'
  349.         
  350.         s = SMTPsender(un, password, srv, from_name = f, use_tls = self.smtp_require_ssl)
  351.         s.send_email(to = to, subject = subject, body = body, cc = cc, bcc = bcc)
  352.  
  353.     send_email = threaded(send_email)
  354.     mailclient = localprefprop(localprefs_key('mailclient'), 'sysdefault')
  355.  
  356.