Beispiel #1
0
def sendMail(document, ext, mtime, mail_config):
    msg = MIMEMultipart()

    msg["Subject"] = "New Scan!"
    msg["From"] = mail_config.mail_from
    msg["To"] = mail_config.mail_to

    mime_type = mime.from_buffer(document).split("/", 1)

    attachment = MIMENonMultipart(mime_type[0], mime_type[1])
    attachment.add_header("Content-Disposition",
                          "attachment",
                          filename="scan-{timestamp}.{ext}".format(
                              timestamp=mtime.strftime("%Y_%m_%d-%H%M%S"),
                              ext=ext))
    attachment.set_payload(document)
    encoders.encode_base64(attachment)
    msg.attach(attachment)
    msg.attach(
        MIMEText("""Hey!

I found a new scan on your printer. You can find it in the attachments :)

Regards
Scan-Bot
"""))

    s = smtplib.SMTP(mail_config.host, mail_config.port)
    s.starttls()
    s.login(mail_config.user, mail_config.password)
    s.send_message(msg)
Beispiel #2
0
    def send(self, document: Document):
        server = smtplib.SMTP_SSL(self.server, self.ssl_port)
        server.login(self.user, self.password)
        message = MIMEMultipart("alternative")
        message["Subject"] = f"Nuovo documento '{document.title}'"
        message["From"] = self.user
        message["To"] = ",".join(self.to)
        environment = Environment(loader=FileSystemLoader(
            searchpath=self.templates_directory))
        text_template = environment.get_template("document.text.jinja2")
        html_template = environment.get_template("document.html.jinja2")

        env = {"document": document}
        part1 = MIMEText(text_template.render(env), "plain")
        part2 = MIMEText(html_template.render(env), "html")

        message.attach(part1)
        message.attach(part2)

        for attachment in document.attachments:
            type_, subtype = attachment.content_type.split("/")
            mime = MIMENonMultipart(_maintype=type_, _subtype=subtype)
            mime.set_payload(attachment.bytes_)
            mime.add_header("Content-Disposition",
                            "attachment",
                            filename=attachment.name)
            encoders.encode_base64(mime)
            message.attach(mime)

        server.sendmail(self.user, self.to, message.as_string())
        server.close()
Beispiel #3
0
def sendPDF(fileName, email):
    smtp_ssl_host = 'smtp.gmail.com'
    smtp_ssl_port = 465
    username = '******'
    password = '******'
    sender = '*****@*****.**'
    targets = [email]

    msg = MIMEMultipart()
    msg['Subject'] = 'Study Plan'
    msg['From'] = sender
    msg['To'] = ', '.join(targets)

    #Source for PDF send: https://bugs.python.org/issue9040
    fp = open(fileName, 'rb')
    attach = MIMENonMultipart('application', 'pdf')
    payload = base64.b64encode(fp.read()).decode('ascii')
    attach.set_payload(payload)
    attach['Content-Transfer-Encoding'] = 'base64'
    fp.close()
    attach.add_header('Content-Disposition', 'attachment', filename = 'StudyPlan.pdf')
    msg.attach(attach)
    #End of found fix

    server = smtplib.SMTP_SSL(smtp_ssl_host, smtp_ssl_port)
    server.login(username, password)

    server.sendmail(sender, targets, msg.as_string())

    server.quit()
    return "Sent study plan to: " + email
Beispiel #4
0
    def upload(self, filename):
        name = os.path.basename(filename)
        size = os.path.getsize(filename)
        cype = guess_type(name)
        if not cype or not cype[0]:
            cype = "text/plain"
        else:
            cype = cype[0]

        url = ("https://www.googleapis.com/upload/drive/v2/files?"
               "uploadType=multipart")

        message = MIMEMultipart('mixed')
        # Message should not write out it's own headers.
        setattr(message, '_write_headers', lambda self: None)

        msg = MIMENonMultipart('application', 'json; charset=UTF-8')
        msg.set_payload(json.dumps({"title": name,  #.replace("'", r"\'"),
                                    "mimeType": cype}))
        message.attach(msg)

        msg = MIMENonMultipart(*cype.split('/'))
        msg.add_header("Content-Transfer-Encoding", "binary")
        msg.set_payload(open(filename).read())
        message.attach(msg)
        
        body = message.as_string()
        bd = message.get_boundary()
        hd = {"Content-Type": 'multipart/related; boundary="%s"' % bd}
        res = self.auth_http("POST", url, body, hd)
        ret = res.read()
        pprint(ret)
Beispiel #5
0
def send_simple_mail(sender, receiver, subject, msgtxt, sending_username, attachments=None):
	# attachment format, each is a tuple of (name, mimetype,contents)
	# content should already be base64 encoded
	msg = MIMEMultipart()
	msg['Subject'] = subject
	msg['To'] = receiver
	msg['From'] = sender
	msg['Date'] = formatdate(localtime=True)
	msg['User-Agent'] = 'pgcommitfest'
	if sending_username:
		msg['X-cfsender'] = sending_username

	msg.attach(MIMEText(msgtxt, _charset='utf-8'))

	if attachments:
		for filename, contenttype, content in attachments:
			main,sub = contenttype.split('/')
			part = MIMENonMultipart(main,sub)
			part.set_payload(content)
			part.add_header('Content-Disposition', 'attachment; filename="%s"' % filename)
			encoders.encode_base64(part)
			msg.attach(part)


	# Just write it to the queue, so it will be transactionally rolled back
	QueuedMail(sender=sender, receiver=receiver, fullmsg=msg.as_string()).save()
Beispiel #6
0
    def upload(self, filename):
        name = os.path.basename(filename)
        size = os.path.getsize(filename)
        cype = guess_type(name)
        if not cype or not cype[0]:
            cype = "text/plain"
        else:
            cype = cype[0]

        url = ("https://www.googleapis.com/upload/drive/v2/files?"
               "uploadType=multipart")

        message = MIMEMultipart('mixed')
        # Message should not write out it's own headers.
        setattr(message, '_write_headers', lambda self: None)

        msg = MIMENonMultipart('application', 'json; charset=UTF-8')
        msg.set_payload(json.dumps({"title": name,  #.replace("'", r"\'"),
                                    "mimeType": cype}))
        message.attach(msg)

        msg = MIMENonMultipart(*cype.split('/'))
        msg.add_header("Content-Transfer-Encoding", "binary")
        msg.set_payload(open(filename).read())
        message.attach(msg)
        
        body = message.as_string()
        bd = message.get_boundary()
        hd = {"Content-Type": 'multipart/related; boundary="%s"' % bd}
        res = self.auth_http("POST", url, body, hd)
        ret = res.read()
        pprint(ret)
        return 
Beispiel #7
0
def send_simple_mail(sender, receiver, subject, msgtxt, attachments=None, bcc=None, sendername=None, receivername=None):
    # attachment format, each is a tuple of (name, mimetype,contents)
    # content should be *binary* and not base64 encoded, since we need to
    # use the base64 routines from the email library to get a properly
    # formatted output message
    msg = MIMEMultipart()
    msg['Subject'] = subject
    msg['To'] = _encoded_email_header(receivername, receiver)
    msg['From'] = _encoded_email_header(sendername, sender)
    msg['Date'] = formatdate(localtime=True)

    msg.attach(MIMEText(msgtxt, _charset='utf-8'))

    if attachments:
        for filename, contenttype, content in attachments:
            main, sub = contenttype.split('/')
            part = MIMENonMultipart(main, sub)
            part.set_payload(content)
            part.add_header('Content-Disposition', 'attachment; filename="%s"' % filename)
            encoders.encode_base64(part)
            msg.attach(part)

    # Just write it to the queue, so it will be transactionally rolled back
    QueuedMail(sender=sender, receiver=receiver, subject=subject, fullmsg=msg.as_string()).save()
    # Any bcc is just entered as a separate email
    if bcc:
        if type(bcc) is list or type(bcc) is tuple:
            bcc = set(bcc)
        else:
            bcc = set((bcc, ))

        for b in bcc:
            QueuedMail(sender=sender, receiver=b, subject=subject, fullmsg=msg.as_string()).save()
Beispiel #8
0
def send_simple_mail(sender, receiver, subject, msgtxt, attachments=None, bcc=None, sendername=None, receivername=None):
	# attachment format, each is a tuple of (name, mimetype,contents)
	# content should be *binary* and not base64 encoded, since we need to
	# use the base64 routines from the email library to get a properly
	# formatted output message
	msg = MIMEMultipart()
	msg['Subject'] = subject
	msg['To'] = _encoded_email_header(receivername, receiver)
	msg['From'] = _encoded_email_header(sendername, sender)
	msg['Date'] = formatdate(localtime=True)

	msg.attach(MIMEText(msgtxt, _charset='utf-8'))

	if attachments:
		for filename, contenttype, content in attachments:
			main,sub = contenttype.split('/')
			part = MIMENonMultipart(main,sub)
			part.set_payload(content)
			part.add_header('Content-Disposition', 'attachment; filename="%s"' % filename)
			encoders.encode_base64(part)
			msg.attach(part)


	# Just write it to the queue, so it will be transactionally rolled back
	QueuedMail(sender=sender, receiver=receiver, fullmsg=msg.as_string()).save()
	# Any bcc is just entered as a separate email
	if bcc:
		QueuedMail(sender=sender, receiver=bcc, fullmsg=msg.as_string()).save()
Beispiel #9
0
def send_simple_mail(sender, receiver, subject, msgtxt, attachments=None, usergenerated=False):
	# attachment format, each is a tuple of (name, mimetype,contents)
	# content should be *binary* and not base64 encoded, since we need to
	# use the base64 routines from the email library to get a properly
	# formatted output message
	msg = MIMEMultipart()
	msg['Subject'] = subject
	msg['To'] = receiver
	msg['From'] = sender
	msg['Date'] = formatdate(localtime=True)
	msg['Message-ID'] = make_msgid()

	msg.attach(MIMEText(msgtxt, _charset='utf-8'))

	if attachments:
		for filename, contenttype, content in attachments:
			main,sub = contenttype.split('/')
			part = MIMENonMultipart(main,sub)
			part.set_payload(content)
			part.add_header('Content-Disposition', 'attachment; filename="%s"' % filename)
			encoders.encode_base64(part)
			msg.attach(part)


	# Just write it to the queue, so it will be transactionally rolled back
	QueuedMail(sender=sender, receiver=receiver, fullmsg=msg.as_string(), usergenerated=usergenerated).save()
Beispiel #10
0
    def post(self, request):
        context = self.get_context_data()

        form, user = context['form'], request.user
        if not form.is_valid():
            return self.get(request)

        s = smtplib.SMTP(settings.EMAIL_HOST, settings.EMAIL_PORT)
        s.starttls()
        if settings.EMAIL_HOST_USER:
            s.login(settings.EMAIL_HOST_USER, settings.EMAIL_HOST_PASSWORD)

        sender = "%s %s (via OxPoints Editor) <%s>" % (user.first_name, user.last_name, user.email)
        recipients = ['%s <%s>' % manager for manager in settings.MANAGERS]

        msg = MIMEMultipart()
        msg['Subject'] = form.cleaned_data['subject']
        msg['From'] = sender
        msg['To'] = ', '.join(recipients)
        msg.attach(MIMEText(form.cleaned_data['message'], 'plain'))

        if request.FILES.get('related_file'):
            related_file = request.FILES['related_file']
            attachment = MIMENonMultipart(*related_file.content_type.split('/', 1))
            attachment.add_header('Content-Disposition', 'attachment', filename=related_file.name)
            attachment.set_payload(related_file.read())
            msg.attach(attachment)

        s.sendmail(sender, recipients, msg.as_string())

        return redirect(reverse('core:request') + '?sent=true')
Beispiel #11
0
    def get_content_block(self, f):
        binding_map = {
            '.xlsx': ('application', 'vnd.openxmlformats-officedocument.spreadsheetml.sheet'),
            '.xls': ('application', 'vnd.ms-excel'),
            '.csv': ('text', 'csv'),
            '.json': ('application', 'json'),
            '.syslog': ('text', 'syslog')
        }

        # Check the file extension to see if it is a supported type
        name_part, ext_part = os.path.splitext(f.name)

        if ext_part.lower() == '.xml':
            cb = tm11.ContentBlock(tm11.ContentBinding(t.CB_STIX_XML_101), f.read())
        else:
            binding_tuple = binding_map.get(ext_part.lower(), None)
            if not binding_tuple:
                logger.error('File extension not supported: %s. Supported extensions: %s' % (ext_part, binding_map.keys()))
                return

            # Read the file and create a MIME message for it
            maintype = binding_tuple[0]
            subtype = binding_tuple[1] # Note: This is MIME subtype, not TAXII subtype
            mime_msg = MIMENonMultipart(maintype, subtype)
            mime_msg.add_header('Content-Disposition', 'attachment', filename=f.name)
            mime_msg.set_payload(f.read())
            encode_base64(mime_msg)

            cb = tm11.ContentBlock('%s/%s' % (maintype, subtype), mime_msg.as_string())

        return cb
Beispiel #12
0
	def attach(self, name, data=None, maintype=None, subtype=None,
		inline=False, filename=None, encoding=None):
		"""Attach a file to this message.

		:param name: Path to the file to attach if data is None, or the name
					 of the file if the ``data`` argument is given
		:param data: Contents of the file to attach, or None if the data is to
					 be read from the file pointed to by the ``name`` argument
		:type data: bytes or a file-like object
		:param maintype: First part of the MIME type of the file -- will be
						 automatically guessed if not given
		:param subtype: Second part of the MIME type of the file -- will be
						automatically guessed if not given
		:param inline: Whether to set the Content-Disposition for the file to
					   "inline" (True) or "attachment" (False)
		:param filename: The file name of the attached file as seen
									by the user in his/her mail client.
		:param encoding: Value of the Content-Encoding MIME header (e.g. "gzip"
						 in case of .tar.gz, but usually empty)
		"""
		self._dirty = True

		if not maintype:
			maintype, guessed_encoding = guess_type(name)
			encoding = encoding or guessed_encoding
			if not maintype:
				maintype, subtype = 'application', 'octet-stream'
			else:
				maintype, _, subtype = maintype.partition('/')

		part = MIMENonMultipart(maintype, subtype)
		part.add_header('Content-Transfer-Encoding', 'base64')

		if encoding:
			part.add_header('Content-Encoding', encoding)

		if data is None:
			with open(name, 'rb') as fp:
				value = fp.read()
			name = os.path.basename(name)
		elif isinstance(data, bytes):
			value = data
		elif hasattr(data, 'read'):
			value = data.read()
		else:
			raise TypeError("Unable to read attachment contents")
		
		part.set_payload(base64.encodestring(value))

		if not filename:
			filename = name
		filename = os.path.basename(filename)
		
		if inline:
			part.add_header('Content-Disposition', 'inline', filename=filename)
			part.add_header('Content-ID', '<%s>' % filename)
			self.embedded.append(part)
		else:
			part.add_header('Content-Disposition', 'attachment', filename=filename)
			self.attachments.append(part)
Beispiel #13
0
def sendmail(text, sender, subject, archive=None):
    if not c.has_option('commitmsg', 'destination'):
        return

    if c.has_option('commitmsg', 'replyto'):
        pieces = []
        for p in c.get('commitmsg', 'replyto').split(','):
            pp = p.strip()
            if pp == '$committer':
                if sender:
                    pieces.append(sender.strip())
                # Don't add fallback sender as committer
            else:
                pieces.append(pp)
        replyto = ', '.join(pieces)
    else:
        replyto = None

    if not sender:
        # No sender specified, so use fallback
        sender = cfg.get('commitmsg', 'fallbacksender')

    (sender_name, sender_address) = email.utils.parseaddr(sender)

    if c.has_option('commitmsg', 'forcesenderaddr'):
        sender_address = c.get('commitmsg', 'forcesenderaddr')

    if sender_name:
        fullsender = "{0} <{1}>".format(sender_name, sender_address)
    else:
        fullsender = sender_address

    for m in c.get('commitmsg', 'destination').split(','):
        msg = MIMEMultipart()
        msg['From'] = fullsender
        msg['To'] = m
        msg['Subject'] = subject
        if replyto:
            msg['Reply-To'] = replyto

        # Don't specify utf8 when doing debugging, because that will encode the output
        # as base64 which is completely useless on the console...
        if debug == 1:
            msg.attach(MIMEText(text))
        else:
            msg.attach(MIMEText(text, _charset='utf-8'))

        if archive:
            part = MIMENonMultipart('application', 'x-gzip')
            part.set_payload(archive)
            part.add_header('Content-Disposition', 'attachment; filename="archive.tar.gz"')
            encoders.encode_base64(part)
            msg.attach(part)

        allmail.append({
            'sender': sender_address,
            'to': m,
            'msg': msg,
        })
Beispiel #14
0
    def prepare_email_message(self):
        """
        Returns a django ``EmailMessage`` or ``EmailMultiAlternatives`` object,
        depending on whether html_message is empty.
        """
        if self.template is not None:
            engine = get_template_engine()
            subject = engine.from_string(self.template.subject).render(self.context)
            plaintext_message = engine.from_string(self.template.content).render(self.context)
            multipart_template = engine.from_string(self.template.html_content)
            html_message = multipart_template.render(self.context)

        else:
            subject = smart_text(self.subject)
            plaintext_message = self.message
            multipart_template = None
            html_message = self.html_message

        connection = connections[self.backend_alias or 'default']

        if html_message:
            if plaintext_message:
                msg = EmailMultiAlternatives(
                    subject=subject, body=plaintext_message, from_email=self.from_email,
                    to=self.to, bcc=self.bcc, cc=self.cc,
                    headers=self.headers, connection=connection)
                msg.attach_alternative(html_message, "text/html")
            else:
                msg = EmailMultiAlternatives(
                    subject=subject, body=html_message, from_email=self.from_email,
                    to=self.to, bcc=self.bcc, cc=self.cc,
                    headers=self.headers, connection=connection)
                msg.content_subtype = 'html'
            if hasattr(multipart_template, 'attach_related'):
                multipart_template.attach_related(msg)

        else:
            msg = EmailMessage(
                subject=subject, body=plaintext_message, from_email=self.from_email,
                to=self.to, bcc=self.bcc, cc=self.cc,
                headers=self.headers, connection=connection)

        for attachment in self.attachments.all():
            if attachment.headers:
                mime_part = MIMENonMultipart(*attachment.mimetype.split('/'))
                mime_part.set_payload(attachment.file.read())
                for key, val in attachment.headers.items():
                    try:
                        mime_part.replace_header(key, val)
                    except KeyError:
                        mime_part.add_header(key, val)
                msg.attach(mime_part)
            else:
                msg.attach(attachment.name, attachment.file.read(), mimetype=attachment.mimetype or None)
            attachment.file.close()

        self._cached_email_message = msg
        return msg
Beispiel #15
0
  def _send_batch_request(self, requests):
    """Sends a batch of requests to the server and processes the HTTP responses.

    Args:
      requests: List of GoogleComputeEngineBase.API_REQUEST named tuples. Must
        contain <= MAX_BATCH_SIZE elements.

    Raises:
      ValueError: If requests has more than MAX_BATCH_SIZE elements.

    Returns:
      List of GoogleComputeEngineBase.BATCH_RESPONSE named tuples, one for
      each element of request parameter.
    """
    if len(requests) > MAX_BATCH_SIZE:
      raise ValueError('Too many requests provided'
                       '(maximum is {0})'.format(MAX_BATCH_SIZE))

    batch = _BatchApiRequest()
    base = urlparse.urlsplit(self.base_url)
    base_path = base.path.rstrip('/')
    for i, request in enumerate(requests):
      msg = MIMENonMultipart('application', 'http')
      msg.add_header('Content-ID', '<{0}>'.format(i))
      msg.set_payload(self._serialize_batch_api_request(base_path, request))
      batch.attach(msg)

    batch_string = batch.as_string()
    content_type = 'multipart/mixed; boundary="{0}"'.format(
        batch.get_boundary())

    url = urlparse.urlunsplit((base.scheme, base.netloc, 'batch',
                               self._create_url_query(None), None))
    response, data = self._send_request(url, 'POST', batch_string, content_type)

    if response.status >= 300:
      error = gce.GceError(
          message=response.reason, status=response.status)
      return [error] * len(requests)  # Return all errors.
    elif not data:
      error = gce.GceError(
          message='Server returned no data', status=response.status)
      return [error] * len(requests)  # Return all errors.

    # Process successful response.
    data = 'content-type: {0}\r\n\r\n'.format(response['content-type']) + data
    parser = FeedParser()
    parser.feed(data)
    response = parser.close()

    responses = []
    for part in response.get_payload():
      responses.append((
          int(RESPONSE_ID_REGEX.match(part['Content-ID']).group(1)),
          self._parse_batch_api_response(part.get_payload())))

    responses.sort(key=lambda r: r[0])
    return [r[1] for r in responses]
Beispiel #16
0
    def send_to_email(self, header, total_fails):
        self.logger.info("Отправляем отчет на email.")
        print(self.mutt_enabled)
        if self.mutt_enabled:
            if "Отчет не сгенерирован" or "Данные обрабатываются" not in header:
                attach_file = ''
            else:
                attach_file = '-a "report/report.csv"'
            mailsubject = "Отчет по {} за {}. (Пропусков: {})".format(
                self.orgname, self.date, total_fails)
            cmd_send_by_email = ' echo "{}" | mutt {} -s "{}" -- {}'.format(
                header, attach_file, mailsubject, self.email)
            temp = subprocess.getoutput(cmd_send_by_email)
            self.logger.debug(temp)
        else:
            mailsubject = "Отчет по {} за {}. (Пропусков: {})".format(
                self.orgname, self.date, total_fails)
            sender = self.smtp_login
            passwd = self.smtp_passwd
            receiver = self.email

            msg = MIMEMultipart()
            msg['From'] = sender
            msg['To'] = receiver
            msg['Subject'] = mailsubject

            if "Отчет не сгенерирован" or "Данные обрабатываются" not in header:
                with open('report/report.csv', encoding='cp1251') as f:
                    report_file = f.read()

                    attachment = MIMENonMultipart('text',
                                                  'csv',
                                                  charset='cp1251')
                    attachment.add_header('Content-Disposition',
                                          'attachment',
                                          filename='report.csv')

                    attachment.set_payload(report_file.encode('cp1251'))
                    msg.attach(attachment)

            msg_body = MIMEText(header)
            msg.attach(msg_body)

            smtp_server_name = self.smtp_server
            port = self.smtp_port

            if port == '465':
                server = smtplib.SMTP_SSL('{}:{}'.format(
                    smtp_server_name, port))
            else:
                server = smtplib.SMTP('{}:{}'.format(smtp_server_name, port))
                server.starttls()  # this is for secure reason

            server.login(sender, passwd)
            server.send_message(msg)
            server.quit()
Beispiel #17
0
def send_simple_mail(sender,
                     receiver,
                     subject,
                     msgtxt,
                     attachments=None,
                     usergenerated=False,
                     cc=None,
                     replyto=None,
                     sendername=None,
                     receivername=None,
                     messageid=None):
    # attachment format, each is a tuple of (name, mimetype,contents)
    # content should be *binary* and not base64 encoded, since we need to
    # use the base64 routines from the email library to get a properly
    # formatted output message
    msg = MIMEMultipart()
    msg['Subject'] = subject
    msg['To'] = _encoded_email_header(receivername, receiver)
    msg['From'] = _encoded_email_header(sendername, sender)
    if cc:
        msg['Cc'] = cc
    if replyto:
        msg['Reply-To'] = replyto
    msg['Date'] = formatdate(localtime=True)
    if messageid:
        msg['Message-ID'] = messageid
    else:
        msg['Message-ID'] = make_msgid()

    msg.attach(MIMEText(msgtxt, _charset='utf-8'))

    if attachments:
        for filename, contenttype, content in attachments:
            main, sub = contenttype.split('/')
            part = MIMENonMultipart(main, sub)
            part.set_payload(content)
            part.add_header('Content-Disposition',
                            'attachment; filename="%s"' % filename)
            encoders.encode_base64(part)
            msg.attach(part)

    # Just write it to the queue, so it will be transactionally rolled back
    QueuedMail(sender=sender,
               receiver=receiver,
               fullmsg=msg.as_string(),
               usergenerated=usergenerated).save()
    if cc:
        # Write a second copy for the cc, wihch will be delivered
        # directly to the recipient. (The sender doesn't parse the
        # message content to extract cc fields).
        QueuedMail(sender=sender,
                   receiver=cc,
                   fullmsg=msg.as_string(),
                   usergenerated=usergenerated).save()
Beispiel #18
0
        def send_report(self, short_description, additional_description, title,
                        report):
            # Create message container - the correct MIME type is multipart/mixed to allow attachment.
            full_email = MIMEMultipart('mixed')
            full_email[
                'Subject'] = '[' + self.conf['subject_keyword'] + '] ' + title
            full_email['From'] = self.conf['from']
            full_email['To'] = self.conf['to']

            # Create the body of the message (a plain-text and an HTML version).
            body = MIMEMultipart('alternative')
            body.attach(
                MIMEText((short_description + "\n\n" +
                          additional_description).encode('utf-8'),
                         'plain',
                         _charset='utf-8'))
            body.attach(
                MIMEText(("""\
                                    <html>
                                      <head></head>
                                      <body>
                                        <p>""" + short_description +
                          """</p><br>
                                        """ + additional_description + """
                                      </body>
                                    </html>
                                    """).encode('utf-8'),
                         'html',
                         _charset='utf-8'))
            full_email.attach(body)

            # Create the attachment of the message in text/csv.
            attachment = MIMENonMultipart('text', 'csv', charset='utf-8')
            attachment.add_header('Content-Disposition',
                                  'attachment',
                                  filename=report['filename'])
            cs = Charset('utf-8')
            cs.body_encoding = BASE64
            attachment.set_payload(report['content'].encode('utf-8'),
                                   charset=cs)
            full_email.attach(attachment)

            # Send the message via SMTP server.
            s = smtplib.SMTP(self.conf['server'], self.conf['port'])
            if self.conf['tls'] == 'yes':
                s.starttls()
            if not self.conf['login'] == '':
                s.login(self.conf['login'], self.conf['password'])
            # sendmail function takes 3 arguments: sender's address, recipient's address
            # and message to send - here it is sent as one string.
            s.sendmail(self.conf['from'], self.conf['to'],
                       full_email.as_string())
            # self.logger.info('email sent')
            s.quit()
Beispiel #19
0
 def send_report(self, date, short_description, additional_description,
                 title, _filename):
     full_email = MIMEMultipart('mixed')
     full_email['Subject'] = date + " " + self.subject
     full_email['From'] = self.sender
     full_email['To'] = self.receipant
     email_addresses = self.receipant.split(',')
     # CSV FILE
     attachment = MIMENonMultipart('plain', 'csv', charset='utf-8')
     attachment.add_header('Content-Disposition',
                           'attachment',
                           filename=_filename[39:len(_filename)])
     attachment.set_payload(open(_filename, "rb").read())
     full_email.attach(attachment)
     # HTML TABLE
     body = MIMEMultipart('alternative')
     body.attach(
         MIMEText(
             (short_description + additional_description).encode('utf-8'),
             'html',
             _charset='utf-8'))
     body.attach(
         MIMEText(("""\
                             <html>
                               <head></head>
                               <body>
                                 <div style="text-align:center">
                                     <strong>
                                         <h1><font color="red">""" + title +
                   """</font></h1>
                                         <h4>""" + short_description +
                   additional_description + """</h4>
                                     </strong>
                                 </div>
                               </body>
                             </html>
                             """).encode('utf-8'),
                  'html',
                  _charset='utf-8'))
     full_email.attach(body)
     s = smtplib.SMTP(self.server, self.port)
     if self.tls == 'yes':
         s.starttls()
     if not self.login == '':
         s.login(self.login, self.password)
     try:
         s.sendmail(self.sender, email_addresses, full_email.as_string())
         s.quit()
     except SMTPException as e:
         print "ERROR %d: %s" % (e.args[0], e.args[1])
    def _attachment_to_cdoc(self, content, content_type, encoder=encoders.encode_base64):
        major, sub = content_type.split('/')
        attachment = MIMENonMultipart(major, sub)
        attachment.set_payload(content)
        encoder(attachment)
        attachment.add_header('Content-Disposition', 'attachment', filename='does_not_matter.txt')

        pseudo_mail = MIMEMultipart()
        pseudo_mail.attach(attachment)

        tmp_mail = SoledadMailAdaptor().get_msg_from_string(MessageClass=Message, raw_msg=pseudo_mail.as_string())

        cdoc = tmp_mail.get_wrapper().cdocs[1]
        return cdoc
    def _attachment_to_cdoc(self, content, content_type, encoder=encoders.encode_base64):
        major, sub = content_type.split('/')
        attachment = MIMENonMultipart(major, sub)
        attachment.set_payload(content)
        encoder(attachment)
        attachment.add_header('Content-Disposition', 'attachment', filename='does_not_matter.txt')

        pseudo_mail = MIMEMultipart()
        pseudo_mail.attach(attachment)

        tmp_mail = SoledadMailAdaptor().get_msg_from_string(MessageClass=Message, raw_msg=pseudo_mail.as_string())

        cdoc = tmp_mail.get_wrapper().cdocs[1]
        return cdoc
Beispiel #22
0
 def _generate_MIME_part(key, content, keytype, headers):
     if not keytype:
         try:
             content.encode("ascii")
             keytype = ("text", "plain")
         except UnicodeError:
             keytype = ("application", "octet-stream")
     submsg = MIMENonMultipart(*keytype)
     content_headers = {'name': key}
     if headers:
         content_headers.update(headers)
     submsg.add_header("Content-disposition", "form-data",
                       **content_headers)
     submsg.set_payload(content)
     return submsg
Beispiel #23
0
    def _form_email(self, recipient_data):
        """
        Form the html email, including mimetype and headers.
        """

        # instatiate the email object and assign headers
        email_message = MIMEMultipart('related')
        email_message.preamble = 'This is a multi-part message in MIME format.'

        if self.txt_path != "":
            txt = MIMEText(PyMailer._prepare_text(self.txt_path,
                                                  recipient_data),
                           'plain',
                           _charset='utf-8')
            # encoders.encode_quopri(txt)
            email_message.attach(txt)

        if self.html_path != "":
            html = MIMEText(PyMailer._prepare_text(self.html_path,
                                                   recipient_data),
                            'html',
                            _charset='utf-8')
            # encoders.encode_quopri(html)
            email_message.attach(html)

        for image in self.images:
            with open(image, 'rb') as f:
                imageMime = MIMEImage(f.read())
            imageMime.add_header('Content-ID', '<%s>' % image)
            email_message.attach(imageMime)

        for attachment in self.attachments:
            with open(attachment[1], 'rb') as f:
                attachmentMime = MIMENonMultipart(attachment[0].split('/')[0],
                                                  attachment[0].split('/')[1])
                attachmentMime.set_payload(f.read())
                if attachment[0].split('/')[0] == 'text':
                    encoders.encode_quopri(attachmentMime)
                attachmentMime.add_header(
                    'Content-Disposition',
                    'attachment; filename=%s' % attachment[1])
                email_message.attach(attachmentMime)

        email_message['From'] = recipient_data.get('sender')
        email_message['To'] = recipient_data.get('recipient')
        email_message['Subject'] = self.subject

        return email_message.as_string()
Beispiel #24
0
    def prepare_email_message(self):
        """
        Returns a django ``EmailMessage`` or ``EmailMultiAlternatives`` object,
        depending on whether html_message is empty.
        """
        subject = smart_text(self.subject)

        if self.template is not None:
            _context = Context(self.context)
            subject = Template(self.template.subject).render(_context)
            message = Template(self.template.content).render(_context)
            html_message = Template(self.template.html_content).render(_context)

        else:
            subject = self.subject
            message = self.message
            html_message = self.html_message

        connection = connections[self.backend_alias or 'default']

        if html_message:
            msg = EmailMultiAlternatives(
                subject=subject, body=message, from_email=self.from_email,
                to=self.to, bcc=self.bcc, cc=self.cc,
                headers=self.headers, connection=connection)
            msg.attach_alternative(html_message, "text/html")
        else:
            msg = EmailMessage(
                subject=subject, body=message, from_email=self.from_email,
                to=self.to, bcc=self.bcc, cc=self.cc,
                headers=self.headers, connection=connection)

        for attachment in self.attachments.all():
            if attachment.headers:
                mime_part = MIMENonMultipart(*attachment.mimetype.split('/'))
                mime_part.set_payload(attachment.file.read())
                for key, val in attachment.headers.items():
                    try:
                        mime_part.replace_header(key, val)
                    except KeyError:
                        mime_part.add_header(key, val)
                msg.attach(mime_part)
            else:
                msg.attach(attachment.name, attachment.file.read(), mimetype=attachment.mimetype or None)
            attachment.file.close()

        self._cached_email_message = msg
        return msg
Beispiel #25
0
    def createMessage(self, recipients):
        msg = MIMEMultipart()
        msg['Subject'] = yamlLoad['SendInfo']['Subject']
        msg['From'] = Sender
        msg['To'] = recipients

        if args.v:
            print(
                colored("Delivering to " + recipients + ", from: " + sender,
                        "yellow"))

        data = MIMEText(yamlLoad['SendInfo']['Body'], 'html')
        msg.attach(data)

        if args.v:
            print(colored("Message to be delivered: \n", "yellow"))
            print(colored(data, "white", "on_blue"))

        if args.p:
            try:
                payloadPath = args.p
                fp = open(payloadPath, 'rb')
                attach = MIMENonMultipart('application', 'exe')
                payload = base64.b64encode(fp.read()).decode('ascii')
                attach.set_payload(payload)
                attach['Content-Transfer-Encoding'] = 'base64'
                nameFile = yamlLoad['SendInfo']['Attachment']
                attach.add_header('Content-Disposition',
                                  'attachment',
                                  filename=nameFile)
                msg.attach(attach)
                fp.close()

                if args.v:
                    print(
                        colored("Name of attachment to be sent: " + nameFile,
                                "yellow"))

            except:
                print(colored("Incorrect file path \n", "yellow"))

        if args.v:
            print(colored("Message created successfuly \n", "green"))

        message = msg.as_string()
        return message
Beispiel #26
0
    def email_files(self):
        if os.getcwd() != self.filePathStorage:
            os.chdir(self.filePathStorage)

        try:
            # Changeable from the json object
            to_address = self.adr1 + ',' + self.adr2 + ',' + self.adr3
            message = self.message
            subject = self.subject + " @" + str(
                self.current_date)  # Added the date here since I needed it.
            files = [self.fileName1, self.fileName2, self.fileName3]

            server = smtplib.SMTP(str(self.host) + ":" + str(self.port))
            server.starttls()
            server.login(self.host_usr, self.host_psw)

            # Setup the email header details
            msg = MIMEMultipart(From=self.host_usr,
                                To=self.adr1 + ',' + self.adr2 + ',' +
                                self.adr3,
                                Date=formatdate(localtime=True),
                                Subject=subject)

            # Setup backend email details
            msg['Subject'] = subject
            msg['To'] = self.adr1 + ',' + self.adr2 + ',' + self.adr3
            msg.attach(MIMEText(message.replace('\\n', '\n')))

            # Loop to attach all files in the files array
            for f in files:
                attachment = MIMENonMultipart('text', 'csv', charset='utf-8')
                attachment.set_payload(open(f, "rb").read())
                encoders.encode_base64(attachment)
                attachment.add_header('Content-Disposition',
                                      'attachment',
                                      filename=f)
                msg.attach(attachment)

            server.sendmail(self.host_usr, to_address, msg.as_string())
        except smtplib.SMTPRecipientsRefused as e:
            print("Invalid address - {to_address}".format(
                to_address=self.adr1 + ',' + self.adr2 + ',' + self.adr3))
        finally:
            print('Done')
            if server:
                server.quit()
Beispiel #27
0
    def upload(self, filename):
        name = os.path.basename(filename)
        entry = self.get_info(name)
        if entry:
            self._delete(entry)
        #print "after check"
        size = os.path.getsize(filename)
        cype = guess_type(name)
        if not cype or not cype[0]:
            cype = "text/plain"
        else:
            cype = cype[0]

        url = "https://api.box.com/2.0/files/content"

        message = MIMEMultipart('mixed')
        # Message should not write out it's own headers.
        setattr(message, '_write_headers', lambda self: None)

        msg = MIMENonMultipart(*cype.split('/'))
        msg.add_header('Content-Disposition',
                       'form-data; name="f"; filename="%s"' % name)
        del msg["MIME-Version"]
        msg.set_payload(open(filename).read())
        message.attach(msg)

        msg = MIMENonMultipart("text", "plain")
        msg.add_header('Content-Disposition', 'form-data; name="folder_id"')
        del msg["Content-Type"]
        del msg["MIME-Version"]
        msg.set_payload('0')
        message.attach(msg)

        body = message.as_string()
        #print body
        #return
        bd = message.get_boundary()
        hd = {"Content-Type": "multipart/form-data; boundary=%s" % bd}
        res = self.auth_http("POST", url, body, hd)
        ret = res.read()

        print(json.loads(ret)["entries"][0]['name'])
Beispiel #28
0
    def upload(self, filename):
        name = os.path.basename(filename)
        entry = self.get_info(name)
        if entry:
            self._delete(entry)
        #print "after check"
        size = os.path.getsize(filename)
        cype = guess_type(name)
        if not cype or not cype[0]:
            cype = "text/plain"
        else:
            cype = cype[0]

        url = "https://api.box.com/2.0/files/content"

        message = MIMEMultipart('mixed')
        # Message should not write out it's own headers.
        setattr(message, '_write_headers', lambda self: None)

        msg = MIMENonMultipart(*cype.split('/'))
        msg.add_header('Content-Disposition',
                       'form-data; name="f"; filename="%s"' % name)
        del msg["MIME-Version"]
        msg.set_payload(open(filename).read())
        message.attach(msg)

        msg = MIMENonMultipart("text", "plain")
        msg.add_header('Content-Disposition', 'form-data; name="folder_id"')
        del msg["Content-Type"]
        del msg["MIME-Version"]
        msg.set_payload('0')
        message.attach(msg)

        body = message.as_string()
        #print body
        #return
        bd = message.get_boundary()
        hd = {"Content-Type": "multipart/form-data; boundary=%s" % bd}
        res = self.auth_http("POST", url, body, hd)
        ret = res.read()

        print(json.loads(ret)["entries"][0]['name'])
Beispiel #29
0
def to_message(message):

    text = None
    if message.body:
        text = MIMENonMultipart("text", "plain")
        payload = message.body
        ctenc = message.body_transfer_encoding
        if ctenc:
            payload = encode_string(ctenc, payload)
            text.add_header('Content-Transfer-Encoding', ctnec)
        text.set_payload(payload, message.body_charset)

    html = None
    if message.html:
        html = MIMENonMultipart("text", "html")
        payload = message.html
        ctenc = message.html_transfer_encoding
        if ctenc:
            payload = encode_string(ctenc, payload)
            html.add_header('Content-Transfer-Encoding', ctnec)
        html.set_payload(payload, message.html_charset)

    body = None
    if text and html:
        body = MIMEMultipart("alternative", _subparts=[html, text])
    elif html:
        body = html
    elif text:
        body = text

    mail = None
    if len(message.attachments) > 1 or (body and message.attachments):
        mail = MIMEMultipart("mixed")
        if body:
            mail.attach(body)
        for attachment in message.attachments:
            mail.attach(attachment_to_message(attachment))
    elif not body and message.attachments:
        mail = attachment_to_message(message.attachments[0])
    elif body:
        mail = body
    return mail
Beispiel #30
0
def build_mms_body(metadata, attachments):

    """Build a MMS body based on metadata and attachments.

    MMS body is built as a multipart/mixed body whose first part is the metadata's JSON representation
    and the other parts are the attachments.

    """

    body = MIMEMultipart(_subtype='mixed')

    # Add MMS metadata (root fields) as a json part
    part = MIMENonMultipart(_maintype='application', _subtype='json')
    part.add_header('Content-Transfer-Encoding', '8bit')
    part.set_payload(payload=json.dumps(metadata, ensure_ascii=False))
    del(part['MIME-Version'])
    body.attach(part)

    for attachment in attachments:
        # Textual attachments
        if isinstance(attachment, basestring):
            part = MIMENonMultipart(_maintype='text', _subtype='plain')
            part.add_header('Content-Transfer-Encoding', '8bit')
            part.set_payload(payload=attachment, charset='utf-8')
            del(part['MIME-Version'])
            body.attach(part)

        # Binary attachments (image, audio or video)
        elif isinstance(attachment, (file, tuple, list)):
            if isinstance(attachment, file):
                mimetype = mimetypes.guess_type(attachment.name, strict=False)[0]
                payload = attachment.read()
            else:
                mimetype = attachment[0]
                payload = attachment[1]
            if not mimetype or not '/' in mimetype:
                error_str = "Invalid Content-Type '{0}' in attachment #{1}"
                raise ContentTypeError(error_str.format(mimetype, attachments.index(attachment)))
            maintype, subtype = mimetype.split('/')
            if not maintype in ('image', 'audio', 'video'):
                error_str = ("Unsupported Content-Type '{0}' in attachment #{1} "
                             "(only image, audio or video are supported)")
                raise ContentTypeError(error_str.format(mimetype, attachments.index(attachment)))
            part = MIMENonMultipart(_maintype=maintype, _subtype=subtype)
            part.add_header('Content-Transfer-Encoding', 'binary')
            part.add_header('Content-Disposition', 'attachment')  # , filename=os.path.basename(attachment.name))
            part.set_payload(payload=payload)
            del(part['MIME-Version'])
            body.attach(part)

    return body
Beispiel #31
0
    def get_content_block(self, f):
        binding_map = {
            '.xlsx': ('application',
                      'vnd.openxmlformats-officedocument.spreadsheetml.sheet'),
            '.xls': ('application', 'vnd.ms-excel'),
            '.csv': ('text', 'csv'),
            '.json': ('application', 'json'),
            '.syslog': ('text', 'syslog')
        }

        # Check the file extension to see if it is a supported type
        name_part, ext_part = os.path.splitext(f.name)

        if ext_part.lower() == '.xml':
            cb = tm11.ContentBlock(tm11.ContentBinding(t.CB_STIX_XML_101),
                                   f.read())
        else:
            binding_tuple = binding_map.get(ext_part.lower(), None)
            if not binding_tuple:
                logger.error(
                    'File extension not supported: %s. Supported extensions: %s'
                    % (ext_part, binding_map.keys()))
                return

            # Read the file and create a MIME message for it
            maintype = binding_tuple[0]
            subtype = binding_tuple[
                1]  # Note: This is MIME subtype, not TAXII subtype
            mime_msg = MIMENonMultipart(maintype, subtype)
            mime_msg.add_header('Content-Disposition',
                                'attachment',
                                filename=f.name)
            mime_msg.set_payload(f.read())
            encode_base64(mime_msg)

            cb = tm11.ContentBlock('%s/%s' % (maintype, subtype),
                                   mime_msg.as_string())

        return cb
Beispiel #32
0
 def get_mime(cls, report, record, language):
     pool = Pool()
     Report = pool.get(report.report_name, type='report')
     with Transaction().set_context(language=language):
         ext, content, _, title = Report.execute([record.id], {
             'action_id': report.id,
         })
     name = '%s.%s' % (title, ext)
     mimetype, _ = mimetypes.guess_type(name)
     if mimetype:
         msg = MIMENonMultipart(*mimetype.split('/'))
         msg.set_payload(content)
         encode_base64(msg)
     else:
         msg = MIMEApplication(content)
     if not isinstance(name, str):
         name = name.encode('utf-8')
     if not isinstance(language, str):
         language = language.encode('utf-8')
     msg.add_header('Content-Disposition',
                    'attachment',
                    filename=('utf-8', language, name))
     return msg
Beispiel #33
0
def send_simple_mail(sender, receiver, subject, msgtxt, attachments=None, usergenerated=False, cc=None, replyto=None, sendername=None, receivername=None, messageid=None):
    # attachment format, each is a tuple of (name, mimetype,contents)
    # content should be *binary* and not base64 encoded, since we need to
    # use the base64 routines from the email library to get a properly
    # formatted output message
    msg = MIMEMultipart()
    msg['Subject'] = subject
    msg['To'] = _encoded_email_header(receivername, receiver)
    msg['From'] = _encoded_email_header(sendername, sender)
    if cc:
        msg['Cc'] = cc
    if replyto:
        msg['Reply-To'] = replyto
    msg['Date'] = formatdate(localtime=True)
    if messageid:
        msg['Message-ID'] = messageid
    else:
        msg['Message-ID'] = make_msgid()

    msg.attach(MIMEText(msgtxt, _charset='utf-8'))

    if attachments:
        for filename, contenttype, content in attachments:
            main, sub = contenttype.split('/')
            part = MIMENonMultipart(main, sub)
            part.set_payload(content)
            part.add_header('Content-Disposition', 'attachment; filename="%s"' % filename)
            encoders.encode_base64(part)
            msg.attach(part)

    # Just write it to the queue, so it will be transactionally rolled back
    QueuedMail(sender=sender, receiver=receiver, fullmsg=msg.as_string(), usergenerated=usergenerated).save()
    if cc:
        # Write a second copy for the cc, wihch will be delivered
        # directly to the recipient. (The sender doesn't parse the
        # message content to extract cc fields).
        QueuedMail(sender=sender, receiver=cc, fullmsg=msg.as_string(), usergenerated=usergenerated).save()
Beispiel #34
0
    def attach(self, name, data=None, maintype=None, subtype=None, inline=False):
        """Attach a file to this message.
        
        :param name: Path to the file to attach if data is None, or the name
                     of the file if the ``data`` argument is given
        :param data: Contents of the file to attach, or None if the data is to
                     be read from the file pointed to by the ``name`` argument
        :type data: bytes or a file-like object
        :param maintype: First part of the MIME type of the file -- will be
                         automatically guessed if not given
        :param subtype: Second part of the MIME type of the file -- will be
                        automatically guessed if not given
        :param inline: Whether to set the Content-Disposition for the file to
                       "inline" (True) or "attachment" (False)
        """
        self._dirty = True
        
        if not maintype:
            maintype, _ = guess_type(name)
            if not maintype:
                maintype, subtype = 'application', 'octet-stream'
            else:
                maintype, _, subtype = maintype.partition('/')

        part = MIMENonMultipart(maintype, subtype)

        if data is None:
            with open(name, 'rb') as fp:
                part.set_payload(fp.read())
            name = os.path.basename(name)
        elif isinstance(data, bytes):
            part.set_payload(data)
        elif hasattr(data, 'read'):
            part.set_payload(data.read())
        else:
            raise TypeError("Unable to read attachment contents")
        
        if inline:
            part.add_header('Content-Disposition', 'inline', filename=name)
            part.add_header('Content-ID', '<%s>' % name)
            self.embedded.append(part)
        else:
            part.add_header('Content-Disposition', 'attachment', filename=name)
            self.attachments.append(part)
Beispiel #35
0
    def attach(self, name, data=None, maintype=None, subtype=None, inline=False):
        """Attach a file to this message.
        
        :param name: Path to the file to attach if data is None, or the name
                     of the file if the ``data`` argument is given
        :param data: Contents of the file to attach, or None if the data is to
                     be read from the file pointed to by the ``name`` argument
        :type data: bytes or a file-like object
        :param maintype: First part of the MIME type of the file -- will be
                         automatically guessed if not given
        :param subtype: Second part of the MIME type of the file -- will be
                        automatically guessed if not given
        :param inline: Whether to set the Content-Disposition for the file to
                       "inline" (True) or "attachment" (False)
        """
        self._dirty = True

        if not maintype:
            maintype, _ = guess_type(name)
            if not maintype:
                maintype, subtype = "application", "octet-stream"
            else:
                maintype, _, subtype = maintype.partition("/")

        part = MIMENonMultipart(maintype, subtype)

        if data is None:
            with open(name, "rb") as fp:
                part.set_payload(fp.read())
            name = os.path.basename(name)
        elif isinstance(data, bytes):
            part.set_payload(data)
        elif hasattr(data, "read"):
            part.set_payload(data.read())
        else:
            raise TypeError("Unable to read attachment contents")

        if inline:
            part.add_header("Content-Disposition", "inline", filename=name)
            part.add_header("Content-ID", "<%s>" % name)
            self.embedded.append(part)
        else:
            part.add_header("Content-Disposition", "attachment", filename=name)
            self.attachments.append(part)
Beispiel #36
0
def attachment_to_message(attachment):
    mtype, stype = attachment.content_type.split('/')
    if attachment.filename:
        msg = MIMENonMultipart(mtype, stype, name=attachment.filename)
    else:
        msg = MIMENonMultipart(mtype, stype)
    if attachment.disposition:
        if attachment.filename:
            msg.add_header('Content-Dispsition', attachment.disposition,
                    filename=attachment.filename)
        else:
            msg.add_header('Content-Disposition', attachment.disposition)
    payload = attachment.data
    ctenc = attachment.transfer_encoding
    if ctenc:
        payload = encode_string(ctenc, payload)
        msg.add_header('Content-Transfer-Encoding', ctenc)
    msg.set_payload(payload, attachment.charset)
    return msg
Beispiel #37
0
    def submit(self):
        """Submit a query and parse the response.

        @return:  The data retrieved from api.php (a dict)

        """
        paramstring = self.http_params()
        while True:
            action = self.params.get("action", "")
            simulate = self._simulate(action)
            if simulate:
                return simulate
            self.site.throttle(write=self.write)
            uri = self.site.scriptpath() + "/api.php"
            ssl = False
            if self.site.family.name in config.available_ssl_project:
                if action == "login" and config.use_SSL_onlogin:
                    ssl = True
                elif config.use_SSL_always:
                    ssl = True
            try:
                if self.mime:
                    # construct a MIME message containing all API key/values
                    container = MIMEMultipart(_subtype='form-data')
                    for key in self.params:
                        # key "file" requires special treatment in a multipart
                        # message
                        if key == "file":
                            local_filename = self.params[key]
                            filetype = mimetypes.guess_type(local_filename)[0] \
                                       or 'application/octet-stream'
                            file_content = file(local_filename, "rb").read()
                            submsg = MIMENonMultipart(*filetype.split("/"))
                            submsg.add_header("Content-disposition",
                                              "form-data", name=key,
                                              filename=local_filename)
                            submsg.set_payload(file_content)
                        else:
                            try:
                                self.params[key].encode("ascii")
                                keytype = ("text", "plain")
                            except UnicodeError:
                                keytype = ("application", "octet-stream")
                            submsg = MIMENonMultipart(*keytype)
                            submsg.add_header("Content-disposition", "form-data",
                                              name=key)
                            submsg.set_payload(self.params[key])
                        container.attach(submsg)
                    # strip the headers to get the HTTP message body
                    body = container.as_string()
                    marker = "\n\n" # separates headers from body
                    eoh = body.find(marker)
                    body = body[ eoh + len(marker): ]
                    # retrieve the headers from the MIME object
                    mimehead = dict(container.items())
                    rawdata = http.request(self.site, uri, ssl, method="POST",
                                           headers=mimehead, body=body)
                else:
                    rawdata = http.request(self.site, uri, ssl, method="POST",
                                headers={'Content-Type':
                                         'application/x-www-form-urlencoded'},
                                body=paramstring)
##                import traceback
##                traceback.print_stack()
##                print rawdata
            except Server504Error:
                pywikibot.log(u"Caught HTTP 504 error; retrying")
                self.wait()
                continue
            #TODO: what other exceptions can occur here?
            except Exception, e:
                # for any other error on the http request, wait and retry
                pywikibot.error(traceback.format_exc())
                pywikibot.log(u"%s, %s" % (uri, paramstring))
                self.wait()
                continue
            if not isinstance(rawdata, unicode):
                rawdata = rawdata.decode(self.site.encoding())
            pywikibot.debug(u"API response received:\n" + rawdata, _logger)
            if rawdata.startswith(u"unknown_action"):
                raise APIError(rawdata[:14], rawdata[16:])
            try:
                result = json.loads(rawdata)
            except ValueError:
                # if the result isn't valid JSON, there must be a server
                # problem.  Wait a few seconds and try again
                pywikibot.warning(
"Non-JSON response received from server %s; the server may be down."
                                 % self.site)
                pywikibot.debug(rawdata, _logger)
                # there might also be an overflow, so try a smaller limit
                for param in self.params:
                    if param.endswith("limit"):
                        value = self.params[param]
                        try:
                            self.params[param] = str(int(value) // 2)
                            pywikibot.output(u"Set %s = %s"
                                             % (param, self.params[param]))
                        except:
                            pass
                self.wait()
                continue
            if not result:
                result = {}
            if type(result) is not dict:
                raise APIError("Unknown",
                               "Unable to process query response of type %s."
                                   % type(result),
                               {'data': result})
            if self['action'] == 'query':
                if 'userinfo' in result.get('query', ()):
                    if hasattr(self.site, '_userinfo'):
                        self.site._userinfo.update(result['query']['userinfo'])
                    else:
                        self.site._userinfo = result['query']['userinfo']
                status = self.site._loginstatus  # save previous login status
                if ( ("error" in result
                            and result["error"]["code"].endswith("limit"))
                      or (status >= 0
                            and self.site._userinfo['name']
                                != self.site._username[status])):
                    # user is no longer logged in (session expired?)
                    # reset userinfo, then make user log in again
                    del self.site._userinfo
                    self.site._loginstatus = -1
                    if status < 0:
                        status = 0  # default to non-sysop login
                    self.site.login(status)
                    # retry the previous query
                    continue
            if "warnings" in result:
                modules = [k for k in result["warnings"] if k != "info"]
                for mod in modules:
                    if '*' in result["warnings"][mod]:
                        text = result["warnings"][mod]['*']
                    elif 'html' in result["warnings"][mod]:
                        # Bugzilla 49978
                        text = result["warnings"][mod]['html']['*']
                    else:
                        # This is just a warning, we shouldn't raise an
                        # exception because of it
                        continue
                    pywikibot.warning(
                        u"API warning (%s): %s"
                        % (mod, text))
            if "error" not in result:
                return result
            if "*" in result["error"]:
                # help text returned
                result['error']['help'] = result['error'].pop("*")
            code = result["error"].pop("code", "Unknown")
            info = result["error"].pop("info", None)
            if code == "maxlag":
                lag = lagpattern.search(info)
                if lag:
                    pywikibot.log(
                        u"Pausing due to database lag: " + info)
                    self.site.throttle.lag(int(lag.group("lag")))
                    continue
            if code in (u'internal_api_error_DBConnectionError', ):
                self.wait()
                continue
            # raise error
            try:
                pywikibot.log(u"API Error: query=\n%s"
                               % pprint.pformat(self.params))
                pywikibot.log(u"           response=\n%s"
                               % result)
                raise APIError(code, info, **result["error"])
            except TypeError:
                raise RuntimeError(result)
Beispiel #38
0
    def attach(self,
               name,
               data=None,
               maintype=None,
               subtype=None,
               inline=False,
               filename=None,
               filename_charset='',
               filename_language='',
               encoding=None):
        """Attach a file to this message.

		:param name: Path to the file to attach if data is None, or the name
					 of the file if the ``data`` argument is given
		:param data: Contents of the file to attach, or None if the data is to
					 be read from the file pointed to by the ``name`` argument
		:type data: bytes or a file-like object
		:param maintype: First part of the MIME type of the file -- will be
						 automatically guessed if not given
		:param subtype: Second part of the MIME type of the file -- will be
						automatically guessed if not given
		:param inline: Whether to set the Content-Disposition for the file to
					   "inline" (True) or "attachment" (False)
		:param filename: The file name of the attached file as seen
									by the user in his/her mail client.
		:param filename_charset: Charset used for the filename paramenter. Allows for 
						attachment names with characters from UTF-8 or Latin 1. See RFC 2231.
		:param filename_language: Used to specify what language the filename is in. See RFC 2231.
		:param encoding: Value of the Content-Encoding MIME header (e.g. "gzip"
						 in case of .tar.gz, but usually empty)
		"""
        self._dirty = True

        if not maintype:
            maintype, guessed_encoding = guess_type(name)
            encoding = encoding or guessed_encoding
            if not maintype:
                maintype, subtype = 'application', 'octet-stream'
            else:
                maintype, _, subtype = maintype.partition('/')

        part = MIMENonMultipart(maintype, subtype)
        part.add_header('Content-Transfer-Encoding', 'base64')

        if encoding:
            part.add_header('Content-Encoding', encoding)

        if data is None:
            with open(name, 'rb') as fp:
                value = fp.read()
            name = os.path.basename(name)
        elif isinstance(data, bytes):
            value = data
        elif hasattr(data, 'read'):
            value = data.read()
        else:
            raise TypeError("Unable to read attachment contents")

        part.set_payload(base64.encodestring(value))

        if not filename:
            filename = name
        filename = os.path.basename(filename)

        if filename_charset or filename_language:
            if not filename_charset:
                filename_charset = 'utf-8'
            # See https://docs.python.org/2/library/email.message.html#email.message.Message.add_header
            # for more information.
            # add_header() in the email module expects its arguments to be ASCII strings. Go ahead and handle
            # the case where these arguments come in as unicode strings, since encoding ASCII strings
            # as UTF-8 can't hurt.
            if sys.version_info < (3, 0):
                filename = (filename_charset.encode('utf-8'),
                            filename_language.encode('utf-8'),
                            filename.encode('utf-8'))
            else:
                filename = (filename_charset, filename_language, filename)

        if inline:
            if sys.version_info < (3, 0):
                part.add_header('Content-Disposition'.encode('utf-8'),
                                'inline'.encode('utf-8'),
                                filename=filename)
                part.add_header('Content-ID'.encode('utf-8'),
                                '<%s>'.encode('utf-8') % filename)
            else:
                part.add_header('Content-Disposition',
                                'inline',
                                filename=filename)
                part.add_header('Content-ID', '<%s>' % filename)
            self.embedded.append(part)
        else:
            if sys.version_info < (3, 0):
                part.add_header('Content-Disposition'.encode('utf-8'),
                                'attachment'.encode('utf-8'),
                                filename=filename)
            else:
                part.add_header('Content-Disposition',
                                'attachment',
                                filename=filename)
            self.attachments.append(part)
Beispiel #39
0
def build_email(mail_to,
                subject,
                body_text,
                mail_from='*****@*****.**',
                reply_to=None,
                attachments=None,
                mime_headers=None):
    """
    Flexible Multipart MIME message builder.

    Implements message building using the "email" Python standard library
    https://docs.python.org/2/library/email-examples.html

    while following recommendations from
    https://stackoverflow.com/questions/3902455/smtp-multipart-alternative-vs-multipart-mixed

    .. seealso::

        - http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52243
        - http://mail.python.org/pipermail/tutor/1999-June/000259.html
        - http://www.bigbold.com/snippets/posts/show/2038
    """
    attachments = attachments or {}
    mime_headers = mime_headers or {}

    # ------------------------------------------
    #                envelope
    # ------------------------------------------

    message = MIMEMultipart('mixed')
    # TODO: Add text for non MIME-aware MUAs
    #message.preamble = 'You will not see this in a MIME-aware mail reader.\n'

    # Address headers
    address_headers = {
        'To': fix_addresslist(AddressList(mail_to)),
        'From': AddressList(mail_from),
        'Reply-To': AddressList(reply_to),
    }

    # Subject header
    mime_headers.update({'Subject': Header(s=subject, charset='utf-8')})

    # Add address headers
    for key, item in address_headers.items():
        if isinstance(item, AddressList):

            # v1
            #for address in format_addresslist(item):
            #    message[key] = address

            # v2
            value = ', '.join(format_addresslist(item))
            if value:
                message[key] = value

    # Add more headers
    for key, value in mime_headers.items():
        #message.add_header(key, value)
        if value:
            message[key] = value

    # ------------------------------------------
    #              email body
    # ------------------------------------------
    body_message = MIMEMultipart('alternative')

    # Start off with a text/plain part
    # https://stackoverflow.com/questions/3902455/smtp-multipart-alternative-vs-multipart-mixed
    body_part1 = MIMEText(body_text, _subtype='plain', _charset='utf-8')
    #body_part1.set_payload(body_text)
    #body_part1.set_charset('utf-8')
    body_message.attach(body_part1)
    message.attach(body_message)

    # TODO: Add a text/html part
    #body_part2 = MIMEText(body_html, 'html')

    # ------------------------------------------
    #            multipart attachments
    # ------------------------------------------
    # from https://docs.python.org/2/library/email-examples.html
    for filename, payload in attachments.items():

        # Guess the content type based on the file's extension.  Encoding
        # will be ignored, although we should check for simple things like
        # gzip'd or compressed files.
        ctype, encoding = mimetypes.guess_type(filename, strict=False)
        #print('ctype, encoding:', ctype, encoding)

        if ctype is None or encoding is not None:
            # No guess could be made, or the file is encoded (compressed), so
            # use a generic bag-of-bits type.
            ctype = 'application/octet-stream'
        maintype, subtype = ctype.split('/', 1)
        #print('maintype, subtype:', maintype, subtype)

        # Create proper MIME part by maintype
        if maintype == 'application' and subtype in ['xml', 'json']:
            part = MIMENonMultipart(maintype, subtype, charset='utf-8')
            part.set_payload(payload.encode('utf-8'), 'utf-8')

        elif maintype == 'text':
            part = MIMEText(payload.encode('utf-8'),
                            _subtype=subtype,
                            _charset='utf-8')
            #part.set_charset('utf-8')

        elif maintype == 'image':
            part = MIMEImage(payload, _subtype=subtype)
        elif maintype == 'audio':
            part = MIMEAudio(payload, _subtype=subtype)
        else:
            part = MIMEBase(maintype, subtype)
            part.set_payload(payload)
            # Encode the payload using Base64 (Content-Transfer-Encoding)
            encoders.encode_base64(part)

        #part = MIMEBase(maintype, subtype, _charset='utf-8')
        # replace forward slashes by dashes
        filename_attachment = filename.lstrip('/\\').replace('/', '-')
        part.add_header('Content-Disposition',
                        'attachment',
                        filename=filename_attachment.encode('utf-8'))
        #part.set_payload(payload.encode('utf-8'))
        #part.set_charset('utf-8')

        # Encode the payload using Base64 (Content-Transfer-Encoding)
        #encoders.encode_base64(part)

        # Add part to multipart message
        message.attach(part)

    payload = message.as_string()

    return payload
Beispiel #40
0
	def attach(self, name, data=None, maintype=None, subtype=None,
		inline=False, filename=None, filename_charset='', filename_language='',
		encoding=None):
		"""Attach a file to this message.

		:param name: Path to the file to attach if data is None, or the name
					 of the file if the ``data`` argument is given
		:param data: Contents of the file to attach, or None if the data is to
					 be read from the file pointed to by the ``name`` argument
		:type data: bytes or a file-like object
		:param maintype: First part of the MIME type of the file -- will be
						 automatically guessed if not given
		:param subtype: Second part of the MIME type of the file -- will be
						automatically guessed if not given
		:param inline: Whether to set the Content-Disposition for the file to
					   "inline" (True) or "attachment" (False)
		:param filename: The file name of the attached file as seen
									by the user in his/her mail client.
		:param filename_charset: Charset used for the filename paramenter. Allows for 
						attachment names with characters from UTF-8 or Latin 1. See RFC 2231.
		:param filename_language: Used to specify what language the filename is in. See RFC 2231.
		:param encoding: Value of the Content-Encoding MIME header (e.g. "gzip"
						 in case of .tar.gz, but usually empty)
		"""
		self._dirty = True

		if not maintype:
			maintype, guessed_encoding = guess_type(name)
			encoding = encoding or guessed_encoding
			if not maintype:
				maintype, subtype = 'application', 'octet-stream'
			else:
				maintype, _, subtype = maintype.partition('/')

		part = MIMENonMultipart(maintype, subtype)
		part.add_header('Content-Transfer-Encoding', 'base64')

		if encoding:
			part.add_header('Content-Encoding', encoding)

		if data is None:
			with open(name, 'rb') as fp:
				value = fp.read()
			name = os.path.basename(name)
		elif isinstance(data, bytes):
			value = data
		elif hasattr(data, 'read'):
			value = data.read()
		else:
			raise TypeError("Unable to read attachment contents")
		
		part.set_payload(base64.encodestring(value))

		if not filename:
			filename = name
		filename = os.path.basename(filename)

		if filename_charset or filename_language:
			if not filename_charset:
				filename_charset = 'utf-8'
			# See https://docs.python.org/2/library/email.message.html#email.message.Message.add_header
			# for more information.
			# add_header() in the email module expects its arguments to be ASCII strings. Go ahead and handle
			# the case where these arguments come in as unicode strings, since encoding ASCII strings
			# as UTF-8 can't hurt.
			if sys.version_info < (3, 0):
				filename=(filename_charset.encode('utf-8'), filename_language.encode('utf-8'), filename.encode('utf-8'))
			else:
				filename=(filename_charset, filename_language, filename)
		
		if inline:
			part.add_header('Content-Disposition', 'inline', filename=filename)
			part.add_header('Content-ID', '<%s>' % filename)
			self.embedded.append(part)
		else:
			part.add_header('Content-Disposition', 'attachment', filename=filename)
			self.attachments.append(part)
Beispiel #41
0
    def _send_batch_request(self, requests):
        """Sends a batch of requests to the server and processes the HTTP responses.

    Args:
      requests: List of GoogleComputeEngineBase.API_REQUEST named tuples. Must
        contain <= MAX_BATCH_SIZE elements.

    Raises:
      ValueError: If requests has more than MAX_BATCH_SIZE elements.

    Returns:
      List of GoogleComputeEngineBase.BATCH_RESPONSE named tuples, one for
      each element of request parameter.
    """
        if len(requests) > MAX_BATCH_SIZE:
            raise ValueError('Too many requests provided'
                             '(maximum is {0})'.format(MAX_BATCH_SIZE))

        batch = _BatchApiRequest()
        base = urlparse.urlsplit(self.base_url)
        base_path = base.path.rstrip('/')
        for i, request in enumerate(requests):
            msg = MIMENonMultipart('application', 'http')
            msg.add_header('Content-ID', '<{0}>'.format(i))
            msg.set_payload(
                self._serialize_batch_api_request(base_path, request))
            batch.attach(msg)

        batch_string = batch.as_string()
        content_type = 'multipart/mixed; boundary="{0}"'.format(
            batch.get_boundary())

        url = urlparse.urlunsplit((base.scheme, base.netloc, 'batch',
                                   self._create_url_query(None), None))
        response, data = self._send_request(url, 'POST', batch_string,
                                            content_type)

        if response.status >= 300:
            error = gce.GceError(message=response.reason,
                                 status=response.status)
            return [error] * len(requests)  # Return all errors.
        elif not data:
            error = gce.GceError(message='Server returned no data',
                                 status=response.status)
            return [error] * len(requests)  # Return all errors.

        # Process successful response.
        data = 'content-type: {0}\r\n\r\n'.format(
            response['content-type']) + data
        parser = FeedParser()
        parser.feed(data)
        response = parser.close()

        responses = []
        for part in response.get_payload():
            responses.append(
                (int(RESPONSE_ID_REGEX.match(part['Content-ID']).group(1)),
                 self._parse_batch_api_response(part.get_payload())))

        responses.sort(key=lambda r: r[0])
        return [r[1] for r in responses]
Beispiel #42
0
    },
    PURPOSE_SET_PASSWORD: {
        'urlname': 'ResetPasswordConfirmation',
        'subject': _l('Reset the password for your %(domain)s account'),
        'template': 'reset/password-mail',
    },
    PURPOSE_DELETE: {
        'urlname': 'DeleteConfirmation',
        'subject': _l('Delete your account on %(domain)s'),
        'template': 'delete/mail',
    },
}

log = logging.getLogger(__name__)
pgp_version = MIMENonMultipart('application', 'pgp-encrypted')
pgp_version.add_header('Content-Description', 'PGP/MIME version identification')
pgp_version.set_payload('Version: 1\n')


@python_2_unicode_compatible
class RegistrationUser(AbstractBaseUser):
    # NOTE: MySQL only allows a 255 character limit
    jid = models.CharField(max_length=255, unique=True, verbose_name='JID')
    email = models.EmailField(null=True, blank=True)
    gpg_fingerprint = models.CharField(max_length=40, null=True, blank=True)

    # when the account was first registered
    registered = models.DateTimeField(auto_now_add=True)
    registration_method = models.SmallIntegerField(choices=REGISTRATION_CHOICES)

    # when the email was confirmed
Beispiel #43
0
        def mock_send_request(path, method, body, content_type):
            self.assertEqual('POST', method)
            self.assertEqual('https://www.googleapis.com/batch', path)
            match = re.match('multipart/mixed; boundary="([^\"]+)"',
                             content_type)
            self.assertTrue(match)
            parts = body.split('--{0}'.format(match.group(1)))
            self.assertEqual(gce_base.MAX_BATCH_SIZE + 2, len(parts))
            self.assertEqual('', parts[0])
            self.assertEqual('--', parts[-1])
            parts = parts[1:-1]

            responses = []
            for part in parts:
                headers, payload = part.split('\n\n', 1)
                headers = parse_headers(headers)
                self.assertEqual('application/http', headers['Content-Type'])
                content_id = headers['Content-ID']
                self.assertTrue(
                    content_id.startswith('<') and content_id.endswith('>'))
                content_id = content_id[1:-1]

                http_headers = payload.split('\n\n', 1)[0]
                split = http_headers.split(
                    '\n', 1)  # Try to split off the http command
                http_request = split[0]
                if len(split) > 1:
                    headers = parse_headers(split[1])

                verb, path = http_request.split(' ')
                self.assertEqual('GET', verb)

                name = re.match('.*/([^/]+)', path).group(1)
                payload = '{{ "kind": "compute#instance", "name": "{0}" }}'.format(
                    name)

                msg = MIMENonMultipart('application', 'http')
                msg.add_header('Content-ID',
                               '<response-{0}>'.format(content_id))
                msg.set_payload(
                    'HTTP/1.1 200 OK\n'
                    'Content-Type: application/json; charset=UTF-8\n'
                    'Content-Length: {0}\n\n'
                    '{1}'.format(len(payload), payload))
                responses.append(msg)

            random.shuffle(responses)
            response = gce_base._BatchApiRequest()
            for r in responses:
                response.attach(r)

            response_string = response.as_string()
            boundary = response.get_boundary()
            response = httplib2.Response({
                'content-type':
                'multipart/mixed; boundary="{0}"'.format(boundary),
                'status':
                200,
                'reason':
                'OK'
            })

            return response, response_string
    def prepare_email_message(self):
        """
        Returns a django ``EmailMessage`` or ``EmailMultiAlternatives`` object,
        depending on whether html_message is empty.
        """
        if get_override_recipients():
            self.to = get_override_recipients()

        if self.template is not None:
            engine = get_template_engine()
            subject = engine.from_string(self.template.subject).render(
                self.context)
            plaintext_message = engine.from_string(
                self.template.content).render(self.context)
            multipart_template = engine.from_string(self.template.html_content)
            html_message = multipart_template.render(self.context)

        else:
            subject = smart_str(self.subject)
            plaintext_message = self.message
            multipart_template = None
            html_message = self.html_message

        connection = connections[self.backend_alias or 'default']
        if isinstance(self.headers, dict) or self.expires_at:
            headers = dict(self.headers or {})
            if self.expires_at:
                headers.update({
                    'Expires':
                    self.expires_at.strftime("%a, %-d %b %H:%M:%S %z")
                })
        else:
            headers = None

        if html_message:
            if plaintext_message:
                msg = EmailMultiAlternatives(subject=subject,
                                             body=plaintext_message,
                                             from_email=self.from_email,
                                             to=self.to,
                                             bcc=self.bcc,
                                             cc=self.cc,
                                             headers=headers,
                                             connection=connection)
                msg.attach_alternative(html_message, "text/html")
            else:
                msg = EmailMultiAlternatives(subject=subject,
                                             body=html_message,
                                             from_email=self.from_email,
                                             to=self.to,
                                             bcc=self.bcc,
                                             cc=self.cc,
                                             headers=headers,
                                             connection=connection)
                msg.content_subtype = 'html'
            if hasattr(multipart_template, 'attach_related'):
                multipart_template.attach_related(msg)

        else:
            msg = EmailMessage(subject=subject,
                               body=plaintext_message,
                               from_email=self.from_email,
                               to=self.to,
                               bcc=self.bcc,
                               cc=self.cc,
                               headers=headers,
                               connection=connection)

        for attachment in self.attachments.all():
            if attachment.headers:
                mime_part = MIMENonMultipart(*attachment.mimetype.split('/'))
                mime_part.set_payload(attachment.file.read())
                for key, val in attachment.headers.items():
                    try:
                        mime_part.replace_header(key, val)
                    except KeyError:
                        mime_part.add_header(key, val)
                msg.attach(mime_part)
            else:
                msg.attach(attachment.name,
                           attachment.file.read(),
                           mimetype=attachment.mimetype or None)
            attachment.file.close()

        self._cached_email_message = msg
        return msg
Beispiel #45
0
    def submit(self):
        """Submit a query and parse the response.

        @return:  The data retrieved from api.php (a dict)

        """
        while True:
            paramstring = self.http_params()
            action = self.params.get("action", "")
            simulate = self._simulate(action)
            if simulate:
                return simulate
            self.site.throttle(write=self.write)
            uri = self.site.scriptpath() + "/api.php"
            ssl = False
            if self.site.family.name in config.available_ssl_project:
                if action == "login" and config.use_SSL_onlogin:
                    ssl = True
                elif config.use_SSL_always:
                    ssl = True
            try:
                if self.mime:
                    # construct a MIME message containing all API key/values
                    container = MIMEMultipart(_subtype='form-data')
                    for key in self.params:
                        # key "file" requires special treatment in a multipart
                        # message
                        if key == "file":
                            local_filename = self.params[key]
                            filetype = mimetypes.guess_type(local_filename)[0] \
                                or 'application/octet-stream'
                            file_content = file(local_filename, "rb").read()
                            submsg = MIMENonMultipart(*filetype.split("/"))
                            submsg.add_header("Content-disposition",
                                              "form-data",
                                              name=key,
                                              filename=local_filename)
                            submsg.set_payload(file_content)
                        else:
                            try:
                                self.params[key].encode("ascii")
                                keytype = ("text", "plain")
                            except UnicodeError:
                                keytype = ("application", "octet-stream")
                            submsg = MIMENonMultipart(*keytype)
                            submsg.add_header("Content-disposition",
                                              "form-data",
                                              name=key)
                            submsg.set_payload(self.params[key])
                        container.attach(submsg)
                    # strip the headers to get the HTTP message body
                    body = container.as_string()
                    marker = "\n\n"  # separates headers from body
                    eoh = body.find(marker)
                    body = body[eoh + len(marker):]
                    # retrieve the headers from the MIME object
                    mimehead = dict(list(container.items()))
                    rawdata = http.request(self.site,
                                           uri,
                                           ssl,
                                           method="POST",
                                           headers=mimehead,
                                           body=body)
                else:
                    rawdata = http.request(
                        self.site,
                        uri,
                        ssl,
                        method="POST",
                        headers={
                            'Content-Type': 'application/x-www-form-urlencoded'
                        },
                        body=paramstring)


#                import traceback
#                traceback.print_stack()
#                print rawdata
            except Server504Error:
                pywikibot.log(u"Caught HTTP 504 error; retrying")
                self.wait()
                continue
            except FatalServerError:
                # This error is not going to be fixed by just waiting
                pywikibot.error(traceback.format_exc())
                raise
            # TODO: what other exceptions can occur here?
            except Exception:
                # for any other error on the http request, wait and retry
                pywikibot.error(traceback.format_exc())
                pywikibot.log(u"%s, %s" % (uri, paramstring))
                self.wait()
                continue
            if not isinstance(rawdata, unicode):
                rawdata = rawdata.decode(self.site.encoding())
            pywikibot.debug(u"API response received:\n" + rawdata, _logger)
            if rawdata.startswith(u"unknown_action"):
                raise APIError(rawdata[:14], rawdata[16:])
            try:
                result = json.loads(rawdata)
            except ValueError:
                # if the result isn't valid JSON, there must be a server
                # problem.  Wait a few seconds and try again
                pywikibot.warning(
                    "Non-JSON response received from server %s; the server may be down."
                    % self.site)
                pywikibot.debug(rawdata, _logger)
                # there might also be an overflow, so try a smaller limit
                for param in self.params:
                    if param.endswith("limit"):
                        value = self.params[param]
                        try:
                            self.params[param] = str(int(value) // 2)
                            pywikibot.output(u"Set %s = %s" %
                                             (param, self.params[param]))
                        except:
                            pass
                self.wait()
                continue
            if not result:
                result = {}
            if not isinstance(result, dict):
                raise APIError("Unknown",
                               "Unable to process query response of type %s." %
                               type(result),
                               data=result)
            if self['action'] == 'query':
                if 'userinfo' in result.get('query', ()):
                    if hasattr(self.site, '_userinfo'):
                        self.site._userinfo.update(result['query']['userinfo'])
                    else:
                        self.site._userinfo = result['query']['userinfo']
                status = self.site._loginstatus  # save previous login status
                if (("error" in result
                     and result["error"]["code"].endswith("limit"))
                        or (status >= 0 and self.site._userinfo['name'] !=
                            self.site._username[status])):
                    # user is no longer logged in (session expired?)
                    # reset userinfo, then make user log in again
                    del self.site._userinfo
                    self.site._loginstatus = -1
                    if status < 0:
                        status = 0  # default to non-sysop login
                    self.site.login(status)
                    # retry the previous query
                    continue
            if "warnings" in result:
                modules = [k for k in result["warnings"] if k != "info"]
                for mod in modules:
                    if '*' in result["warnings"][mod]:
                        text = result["warnings"][mod]['*']
                    elif 'html' in result["warnings"][mod]:
                        # Bugzilla 49978
                        text = result["warnings"][mod]['html']['*']
                    else:
                        # This is just a warning, we shouldn't raise an
                        # exception because of it
                        continue
                    pywikibot.warning(u"API warning (%s): %s" % (mod, text))
            if "error" not in result:
                return result
            if "*" in result["error"]:
                # help text returned
                result['error']['help'] = result['error'].pop("*")
            code = result["error"].pop("code", "Unknown")
            info = result["error"].pop("info", None)
            if code == "maxlag":
                lag = lagpattern.search(info)
                if lag:
                    pywikibot.log(u"Pausing due to database lag: " + info)
                    self.site.throttle.lag(int(lag.group("lag")))
                    continue
            if code.startswith(u'internal_api_error_'):
                self.wait()
                continue
            # bugs 46535, 62126, 64494
            # maybe removed when it 46535 is solved
            if code == "failed-save" and action == 'wbeditentity':
                try:
                    message = result["error"]["messages"]["0"]["name"]
                except KeyError:
                    message = None
                if message == u'edit-already-exists':
                    self.wait()
                    continue
            # raise error
            try:
                pywikibot.log(u"API Error: query=\n%s" %
                              pprint.pformat(self.params))
                pywikibot.log(u"           response=\n%s" % result)
                raise APIError(code, info, **result["error"])
            except TypeError:
                raise RuntimeError(result)
Beispiel #46
0
        'subject': _('Your new account on %(domain)s'),
    },
    NEW_PURPOSE_SET_PASSWORD: {
        'subject': _('Reset the password for your %(domain)s account'),
    },
    NEW_PURPOSE_SET_EMAIL: {
        'subject': _l('Confirm the email address for your %(domain)s account'),
    },
    NEW_PURPOSE_DELETE: {
        'subject': _l('Delete your account on %(domain)s'),
    },
}

log = logging.getLogger(__name__)
pgp_version = MIMENonMultipart('application', 'pgp-encrypted')
pgp_version.add_header('Content-Description',
                       'PGP/MIME version identification')
pgp_version.set_payload('Version: 1\n')


@python_2_unicode_compatible
class RegistrationUser(XmppBackendUser):
    # NOTE: MySQL only allows a 255 character limit
    jid = models.CharField(max_length=255, unique=True, verbose_name='JID')
    email = models.EmailField(null=True, blank=True)
    gpg_fingerprint = models.CharField(max_length=40, null=True, blank=True)

    # when the account was first registered
    registered = models.DateTimeField(auto_now_add=True)
    registration_method = models.SmallIntegerField(
        choices=REGISTRATION_CHOICES)
Beispiel #47
0
    def send(cls,
             to='',
             cc='',
             bcc='',
             subject='',
             body='',
             files=None,
             record=None,
             reports=None,
             attachments=None):
        pool = Pool()
        User = pool.get('res.user')
        ActionReport = pool.get('ir.action.report')
        Attachment = pool.get('ir.attachment')
        transaction = Transaction()
        user = User(transaction.user)

        Model = pool.get(record[0])
        record = Model(record[1])

        body_html = HTML_EMAIL % {
            'subject': subject,
            'body': body,
            'signature': user.signature or '',
        }
        content = MIMEMultipart('alternative')
        if html2text:
            body_text = HTML_EMAIL % {
                'subject': subject,
                'body': body,
                'signature': '',
            }
            converter = html2text.HTML2Text()
            body_text = converter.handle(body_text)
            if user.signature:
                body_text += '\n-- \n' + converter.handle(user.signature)
            part = MIMEText(body_text, 'plain', _charset='utf-8')
            content.attach(part)
        part = MIMEText(body_html, 'html', _charset='utf-8')
        content.attach(part)
        if files or reports or attachments:
            msg = MIMEMultipart('mixed')
            msg.attach(content)
            if files is None:
                files = []
            else:
                files = list(files)

            for report_id in (reports or []):
                report = ActionReport(report_id)
                Report = pool.get(report.report_name, type='report')
                ext, content, _, title = Report.execute([record.id], {
                    'action_id': report.id,
                })
                name = '%s.%s' % (title, ext)
                if isinstance(content, str):
                    content = content.encode('utf-8')
                files.append((name, content))
            if attachments:
                files += [(a.name, a.data)
                          for a in Attachment.browse(attachments)]
            for name, data in files:
                mimetype, _ = mimetypes.guess_type(name)
                if mimetype:
                    attachment = MIMENonMultipart(*mimetype.split('/'))
                    attachment.set_payload(data)
                    encode_base64(attachment)
                else:
                    attachment = MIMEApplication(data)
                attachment.add_header('Content-Disposition',
                                      'attachment',
                                      filename=('utf-8', '', name))
                msg.attach(attachment)
        else:
            msg = content
        from_ = config.get('email', 'from')
        set_from_header(msg, from_, user.email or from_)
        msg['To'] = ', '.join(formataddr(a) for a in getaddresses([to]))
        msg['Cc'] = ', '.join(formataddr(a) for a in getaddresses([cc]))
        msg['Subject'] = Header(subject, 'utf-8')

        to_addrs = list(
            filter(
                None,
                map(str.strip,
                    _get_emails(to) + _get_emails(cc) + _get_emails(bcc))))
        sendmail_transactional(from_,
                               to_addrs,
                               msg,
                               datamanager=SMTPDataManager(strict=True))

        email = cls(recipients=to,
                    recipients_secondary=cc,
                    recipients_hidden=bcc,
                    addresses=[{
                        'address': a
                    } for a in to_addrs],
                    subject=subject,
                    body=body,
                    resource=record)
        email.save()
        with Transaction().set_context(_check_access=False):
            attachments_ = []
            for name, data in files:
                attachments_.append(
                    Attachment(resource=email, name=name, data=data))
            Attachment.save(attachments_)
        return email
Beispiel #48
0
def send_email(smtp, recipients, cc, subject, content, csv_reports):
    """Sends an email with attachment.
    Refer to https://gist.github.com/BietteMaxime/f75ae41f7b4557274a9f

    Args:
        smtp: A dictionary containing smtp info:
            - smtp_url
            - smtp_auth_username # optional
            - smtp_auth_password # optional
            - smtp_from
        recipients: To whom to send the email.
        cc: To whom to cc the email.
        subject: Email subject.
        content: Email body content
        csv_reports: List of dictionaries containing "filename", "data" to
            construct CSV attachments.

    Returns:
        None
    """
    if not isinstance(smtp, dict):
        logger.warning("smtp is not a dictionary. Skip.")
        return

    sender = smtp.get("smtp_from", None)
    smtp_url = smtp.get("smtp_url", None)
    smtp_auth_username = smtp.get("smtp_auth_username", None)
    smtp_auth_password = smtp.get("smtp_auth_password", None)
    if sender is None or smtp_url is None:
        logger.warning("Some fields in smtp %s is None. Skip.", smtp)
        return

    # Create message container - the correct MIME type is multipart/mixed
    # to allow attachment.
    full_email = MIMEMultipart("mixed")
    full_email["Subject"] = subject
    full_email["From"] = sender
    full_email["To"] = ", ".join(recipients)
    full_email["CC"] = ", ".join(cc)

    # Create the body of the message (a plain-text version).
    content = content.encode(ENCODING)
    content = MIMEText(content, "plain", _charset=ENCODING)
    full_email.attach(content)

    # Create the attachment of the message in text/csv.
    for report in csv_reports:
        attachment = MIMENonMultipart("text", "csv", charset=ENCODING)
        attachment.add_header("Content-Disposition",
                              "attachment",
                              filename=report["filename"])
        cs = Charset(ENCODING)
        cs.body_encoding = BASE64
        attachment.set_payload(report["data"].encode(ENCODING), charset=cs)
        full_email.attach(attachment)

    try:
        with smtplib.SMTP(smtp_url) as server:
            if smtp_auth_username is not None and smtp_auth_password is not None:
                server.starttls()
                server.login(smtp_auth_username, smtp_auth_password)

            receivers = recipients + cc
            server.sendmail(sender, receivers, full_email.as_string())
            logger.info("Successfully sent email to %s and cc %s",
                        ", ".join(recipients), ", ".join(cc))
    except smtplib.SMTPAuthenticationError:
        logger.warning("The server didn\'t accept the user\\password "
                       "combination.")
    except smtplib.SMTPServerDisconnected:
        logger.warning("Server unexpectedly disconnected")
    except smtplib.SMTPException as e:
        logger.exception("SMTP error occurred: %s", e)
Beispiel #49
0
 def pgp_version(self):
     pgp_version = MIMENonMultipart('application', 'pgp-encrypted')
     pgp_version.add_header('Content-Description', 'PGP/MIME version identification')
     pgp_version.set_payload('Version: 1\n')
     return pgp_version