home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 January / maximum-cd-2011-01.iso / DiscContents / calibre-0.7.26.msi / file_1499 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-10-31  |  9.7 KB  |  253 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. from __future__ import with_statement
  5. __license__ = 'GPL 3'
  6. __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
  7. __docformat__ = 'restructuredtext en'
  8. import sys
  9. import traceback
  10. import os
  11. from email import encoders
  12. from calibre import isbytestring
  13.  
  14. def create_mail(from_, to, subject, text = None, attachment_data = None, attachment_type = None, attachment_name = None):
  15.     MIMEMultipart = MIMEMultipart
  16.     import email.mime.multipart
  17.     outer = MIMEMultipart()
  18.     outer['Subject'] = subject
  19.     outer['To'] = to
  20.     outer['From'] = from_
  21.     outer.preamble = 'You will not see this in a MIME-aware mail reader.\n'
  22.     if text is not None:
  23.         MIMEText = MIMEText
  24.         import email.mime.text
  25.         if isbytestring(text):
  26.             msg = MIMEText(text)
  27.         else:
  28.             msg = MIMEText(text, 'plain', 'utf-8')
  29.         outer.attach(msg)
  30.     
  31.     if attachment_data is not None:
  32.         MIMEBase = MIMEBase
  33.         import email.mime.base
  34.         
  35.         try:
  36.             (maintype, subtype) = attachment_type.split('/', 1)
  37.         except AttributeError:
  38.             (maintype, subtype) = ('application', 'octet-stream')
  39.  
  40.         msg = MIMEBase(maintype, subtype)
  41.         msg.set_payload(attachment_data)
  42.         encoders.encode_base64(msg)
  43.         msg.add_header('Content-Disposition', 'attachment', filename = attachment_name)
  44.         outer.attach(msg)
  45.     
  46.     return outer.as_string()
  47.  
  48.  
  49. def get_mx(host, verbose = 0):
  50.     import dns.resolver as dns
  51.     if verbose:
  52.         print 'Find mail exchanger for', host
  53.     
  54.     answers = list(dns.resolver.query(host, 'MX'))
  55.     answers.sort(cmp = (lambda x, y: cmp(int(getattr(x, 'preference', sys.maxint)), int(getattr(y, 'preference', sys.maxint)))))
  56.     return _[1]
  57.  
  58.  
  59. def sendmail_direct(from_, to, msg, timeout, localhost, verbose):
  60.     import smtplib
  61.     hosts = get_mx(to.split('@')[-1].strip(), verbose)
  62.     timeout = None
  63.     s = smtplib.SMTP(timeout = timeout, local_hostname = localhost)
  64.     s.set_debuglevel(verbose)
  65.     if not hosts:
  66.         raise ValueError('No mail server found for address: %s' % to)
  67.     hosts
  68.     last_error = None
  69.     last_traceback = None
  70.     for host in hosts:
  71.         
  72.         try:
  73.             s.connect(host, 25)
  74.             s.sendmail(from_, [
  75.                 to], msg)
  76.             return s.quit()
  77.         continue
  78.         except Exception:
  79.             e = None
  80.             last_error = e
  81.             last_traceback = traceback.format_exc()
  82.             continue
  83.         
  84.  
  85.     
  86.     if last_error is not None:
  87.         print last_traceback
  88.         raise IOError('Failed to send mail: ' + repr(last_error))
  89.     last_error is not None
  90.  
  91.  
  92. def sendmail(msg, from_, to, localhost = None, verbose = 0, timeout = 30, relay = None, username = None, password = None, encryption = 'TLS', port = -1):
  93.     if relay is None:
  94.         for x in to:
  95.             return sendmail_direct(from_, x, msg, timeout, localhost, verbose)
  96.         
  97.     
  98.     import smtplib
  99.     cls = None if encryption == 'TLS' else smtplib.SMTP_SSL
  100.     timeout = None
  101.     port = int(port)
  102.     s = cls(timeout = timeout, local_hostname = localhost)
  103.     s.set_debuglevel(verbose)
  104.     if port < 0:
  105.         port = None if encryption == 'TLS' else 465
  106.     
  107.     s.connect(relay, port)
  108.     if encryption == 'TLS':
  109.         s.starttls()
  110.         s.ehlo()
  111.     
  112.     if username is not None and password is not None:
  113.         if encryption == 'SSL':
  114.             s.sock = s.file.sslobj
  115.         
  116.         s.login(username, password)
  117.     
  118.     s.sendmail(from_, to, msg)
  119.     return s.quit()
  120.  
  121.  
  122. def option_parser():
  123.     
  124.     try:
  125.         OptionParser = OptionParser
  126.         import calibre.utils.config
  127.         OptionParser
  128.     except ImportError:
  129.         OptionParser = OptionParser
  130.         import optparse
  131.  
  132.     import textwrap
  133.     parser = OptionParser(textwrap.dedent('    %prog [options] [from to text]\n\n    Send mail using the SMTP protocol. %prog has two modes of operation. In the\n    compose mode you specify from to and text and these are used to build and\n    send an email message. In the filter mode, %prog reads a complete email\n    message from STDIN and sends it.\n\n    text is the body of the email message.\n    If text is not specified, a complete email message is read from STDIN.\n    from is the email address of the sender and to is the email address\n    of the recipient. When a complete email is read from STDIN, from and to\n    are only used in the SMTP negotiation, the message headers are not modified.\n    '))
  134.     c = parser.add_option_group('COMPOSE MAIL', 'Options to compose an email. Ignored if text is not specified').add_option
  135.     c('-a', '--attachment', help = 'File to attach to the email')
  136.     c('-s', '--subject', help = 'Subject of the email')
  137.     parser.add_option('-l', '--localhost', help = 'Host name of localhost. Used when connecting to SMTP server.')
  138.     r = parser.add_option_group('SMTP RELAY', 'Options to use an SMTP relay server to send mail. calibre will try to send the email directly unless --relay is specified.').add_option
  139.     r('-r', '--relay', help = 'An SMTP relay server to use to send mail.')
  140.     r('-p', '--port', default = -1, help = 'Port to connect to on relay server. Default is to use 465 if encryption method is SSL and 25 otherwise.')
  141.     r('-u', '--username', help = 'Username for relay')
  142.     r('-p', '--password', help = 'Password for relay')
  143.     r('-e', '--encryption-method', default = 'TLS', choices = [
  144.         'TLS',
  145.         'SSL'], help = 'Encryption method to use when connecting to relay. Choices are TLS and SSL. Default is TLS.')
  146.     parser.add_option('-o', '--outbox', help = 'Path to maildir folder to store failed email messages in.')
  147.     parser.add_option('-f', '--fork', default = False, action = 'store_true', help = 'Fork and deliver message in background. If you use this option, you should also use --outbox to handle delivery failures.')
  148.     parser.add_option('-t', '--timeout', help = 'Timeout for connection')
  149.     parser.add_option('-v', '--verbose', default = 0, action = 'count', help = 'Be more verbose')
  150.     return parser
  151.  
  152.  
  153. def extract_email_address(raw):
  154.     parseaddr = parseaddr
  155.     import email.utils
  156.     return parseaddr(raw)[-1]
  157.  
  158.  
  159. def compose_mail(from_, to, text, subject = None, attachment = None, attachment_name = None):
  160.     attachment_type = None
  161.     attachment_data = None
  162.     if attachment is not None:
  163.         
  164.         try:
  165.             guess_type = guess_type
  166.             import calibre
  167.             guess_type
  168.         except ImportError:
  169.             guess_type = guess_type
  170.             import mimetypes
  171.  
  172.         attachment_data = None if hasattr(attachment, 'read') else open(attachment, 'rb').read()
  173.         attachment_type = guess_type(getattr(attachment, 'name', attachment))[0]
  174.         if attachment_name is None:
  175.             attachment_name = os.path.basename(getattr(attachment, 'name', attachment))
  176.         
  177.     
  178.     subject = None if subject else 'no subject'
  179.     return create_mail(from_, to, subject, text = text, attachment_data = attachment_data, attachment_type = attachment_type, attachment_name = attachment_name)
  180.  
  181.  
  182. def main(args = sys.argv):
  183.     parser = option_parser()
  184.     (opts, args) = parser.parse_args(args)
  185.     if len(args) > 1:
  186.         msg = compose_mail(args[1], args[2], args[3], subject = opts.subject, attachment = opts.attachment)
  187.         (from_, to) = args[1:3]
  188.         (efrom, eto) = map(extract_email_address, (from_, to))
  189.         eto = [
  190.             eto]
  191.     else:
  192.         msg = sys.stdin.read()
  193.         Parser = Parser
  194.         import email.parser
  195.         getaddresses = getaddresses
  196.         import email.utils
  197.         eml = Parser.parsestr(msg, headersonly = True)
  198.         tos = eml.get_all('to', [])
  199.         ccs = eml.get_all('cc', [])
  200.         eto = getaddresses(tos + ccs)
  201.         if not eto:
  202.             raise ValueError('Email from STDIN does not specify any recipients')
  203.         eto
  204.         efrom = getaddresses(eml.get_all('from', []))
  205.         if not efrom:
  206.             raise ValueError('Email from STDIN does not specify a sender')
  207.         efrom
  208.         efrom = efrom[0]
  209.     outbox = None
  210.     if opts.outbox is not None:
  211.         outbox = os.path.abspath(os.path.expanduser(opts.outbox))
  212.         Maildir = Maildir
  213.         import mailbox
  214.         outbox = Maildir(opts.outbox, factory = None)
  215.     
  216.     if opts.fork:
  217.         if os.fork() != 0:
  218.             return 0
  219.     
  220.     
  221.     try:
  222.         sendmail(msg, efrom, eto, localhost = opts.localhost, verbose = opts.verbose, timeout = opts.timeout, relay = opts.relay, username = opts.username, password = opts.password, port = opts.port, encryption = opts.encryption_method)
  223.     except:
  224.         if outbox is not None:
  225.             outbox.add(msg)
  226.             print 'Delivery failed. Message saved to', opts.outbox
  227.         
  228.         raise 
  229.  
  230.     return 0
  231.  
  232.  
  233. def config(defaults = None):
  234.     Config = Config
  235.     StringConfig = StringConfig
  236.     import calibre.utils.config
  237.     desc = _('Control email delivery')
  238.     c = None if defaults is None else StringConfig(defaults, desc)
  239.     c.add_opt('from_')
  240.     c.add_opt('accounts', default = { })
  241.     c.add_opt('relay_host')
  242.     c.add_opt('relay_port', default = 25)
  243.     c.add_opt('relay_username')
  244.     c.add_opt('relay_password')
  245.     c.add_opt('encryption', default = 'TLS', choices = [
  246.         'TLS',
  247.         'SSL'])
  248.     return c
  249.  
  250. if __name__ == '__main__':
  251.     sys.exit(main())
  252.  
  253.