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