Beispiel #1
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 #2
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 #3
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()
    def addAttachment(self, attachment, filename, mimetype=None):
        if not mimetype:
            mimetype = mimetypes.guess_type(filename)[0]
        if not mimetype:
            raise Exception("could not determine MIME type for ", filename)
        if "/" in mimetype:
            major, minor = mimetype.split("/")
        else:
            major = mimetype
            minor = None
        if not self.hasAttachments:
            body = self.msg.set_payload()
            newMsg = MIMEMultipart()
            newMsg.attach(MIMEText(body))

            for header, value in self.msg.items():
                newMsg[header] = value

            self.msg = newMsg
            self.hasAttachments = True
        subMessage = MIMENonMultipart(major, minor, name=filename)
        subMessage.set_payload(attachment)

        if major == "text":
            encoder = Encoders.encode_quopri
        else:
            encoder = Encoders.encode_base64
        encoder(subMessage)
        self.msg.attach(subMessage)
Beispiel #5
0
  def _execute(self, http, order, requests):
    """Serialize batch request, send to server, process response.

    Args:
      http: httplib2.Http, an http object to be used to make the request with.
      order: list, list of request ids in the order they were added to the
        batch.
      request: list, list of request objects to send.

    Raises:
      httplib2.Error if a transport error has occured.
      apiclient.errors.BatchError if the response is the wrong format.
    """
    message = MIMEMultipart('mixed')
    # Message should not write out it's own headers.
    setattr(message, '_write_headers', lambda self: None)

    # Add all the individual requests.
    for request_id in order:
      request = requests[request_id]

      msg = MIMENonMultipart('application', 'http')
      msg['Content-Transfer-Encoding'] = 'binary'
      msg['Content-ID'] = self._id_to_header(request_id)

      body = self._serialize_request(request)
      msg.set_payload(body)
      message.attach(msg)

    body = message.as_string()

    headers = {}
    headers['content-type'] = ('multipart/mixed; '
                               'boundary="%s"') % message.get_boundary()

    resp, content = http.request(self._batch_uri, 'POST', body=body,
                                 headers=headers)

    if resp.status >= 300:
      raise HttpError(resp, content, self._batch_uri)

    # Now break out the individual responses and store each one.
    boundary, _ = content.split(None, 1)

    # Prepend with a content-type header so FeedParser can handle it.
    header = 'content-type: %s\r\n\r\n' % resp['content-type']
    for_parser = header + content

    parser = FeedParser()
    parser.feed(for_parser)
    mime_response = parser.close()

    if not mime_response.is_multipart():
      raise BatchError("Response not in multipart/mixed format.", resp,
          content)

    for part in mime_response.get_payload():
      request_id = self._header_to_id(part['Content-ID'])
      headers, content = self._deserialize_response(part.get_payload())
      self._responses[request_id] = (headers, content)
Beispiel #6
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 #7
0
def formatMail(mailText):
    """returns a mail with headers and content properly formatted as
	a bytestring and MIME.

	mailText must be a unicode instance or pure ASCII
	"""
    rawHeaders, rawBody = mailText.split("\n\n", 1)
    cs = charset.Charset("utf-8")
    cs.body_encoding = charset.QP
    cs.header_encoding = charset.QP
    # they've botched MIMEText so bad it can't really generate
    # quoted-printable UTF-8 any more.  So, let's forget MIMEText:
    msg = MIMENonMultipart("text", "plain", charset="utf-8")
    msg.set_payload(rawBody, charset=cs)

    for key, value in Parser().parsestr(rawHeaders.encode("utf-8")).items():
        if re.match("[ -~]*$", value):
            # it's plain ASCII, don't needlessly uglify output
            msg[key] = value
        else:
            msg[key] = Header(value, cs)
    msg["Date"] = emailutils.formatdate(time.time(),
                                        localtime=False,
                                        usegmt=True)
    msg["X-Mailer"] = "DaCHS VO Server"
    return msg.as_string()
Beispiel #8
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 #9
0
def send_sms_email(filepath, new_door_state):
    """ Sends the email for door status change. """
    config = configparser.ConfigParser()
    config.read(filepath)
    smtp_server = config.get('smtp', 'smtp_server')
    smtp_port = config.get('smtp', 'smtp_port')
    smtp_user = config.get('smtp', 'smtp_user')
    smtp_password = config.get('smtp', 'smtp_password')

    server = smtplib.SMTP(smtp_server, smtp_port)
    server.starttls()
    server.login(smtp_user, smtp_password)
    time.sleep(1)

    msg = ""
    for email_addr, when_sms in config.items('email'):
        send_message = True
        if (new_door_state == "Open"):
            if (when_sms == "closed"):
                send_message = False
        if send_message:
            mmsg2 = MIMENonMultipart('text', 'plain', charset='utf-8')
            mmsg2["Subject"] = "Door: " + new_door_state
            mmsg2["From"] = "*****@*****.**"
            mmsg2["To"] = email_addr
            mmsg2["Cc"] = ""
            msg = " "
            mmsg2.set_payload(msg)
            server.sendmail(mmsg2["From"],
                            mmsg2["To"].split(",") + mmsg2["Cc"].split(","),
                            mmsg2.as_string())
    server.quit()
Beispiel #10
0
    def as_message(self, escape_addresses=True):
        # http://wordeology.com/computer/how-to-send-good-unicode-email-with-python.html
        # http://stackoverflow.com/questions/31714221/how-to-send-an-email-with-quoted
        # http://stackoverflow.com/questions/9403265/how-do-i-use-python/9509718#9509718
        charset = Charset('utf-8')
        charset.header_encoding = QP
        charset.body_encoding = QP
        msg = MIMEMultipart()

        # Headers
        unixfrom = "From %s %s" % (
            self.sender.address, self.archived_date.strftime("%c"))
        header_from = self.sender.address
        if self.sender.name and self.sender.name != self.sender.address:
            header_from = "%s <%s>" % (self.sender.name, header_from)
        header_to = self.mailinglist.name
        if escape_addresses:
            header_from = header_from.replace("@", " at ")
            header_to = header_to.replace("@", " at ")
            unixfrom = unixfrom.replace("@", " at ")
        msg.set_unixfrom(unixfrom)
        headers = (
            ("From", header_from),
            ("To", header_to),
            ("Subject", self.subject),
            )
        for header_name, header_value in headers:
            if not header_value:
                continue
            try:
                msg[header_name] = header_value.encode('ascii')
            except UnicodeEncodeError:
                msg[header_name] = Header(
                    header_value.encode('utf-8'), charset).encode()
        tz = get_fixed_timezone(self.timezone)
        header_date = self.date.astimezone(tz).replace(microsecond=0)
        # Date format: http://tools.ietf.org/html/rfc5322#section-3.3
        msg["Date"] = header_date.strftime("%a, %d %b %Y %H:%M:%S %z")
        msg["Message-ID"] = "<%s>" % self.message_id
        if self.in_reply_to:
            msg["In-Reply-To"] = self.in_reply_to

        # Body
        content = self.ADDRESS_REPLACE_RE.sub(r"\1(a)\2", self.content)
        # Don't use MIMEText, it won't encode to quoted-printable
        textpart = MIMENonMultipart("text", "plain", charset='utf-8')
        textpart.set_payload(content, charset=charset)
        msg.attach(textpart)

        # Attachments
        for attachment in self.attachments.order_by("counter"):
            mimetype = attachment.content_type.split('/', 1)
            part = MIMEBase(mimetype[0], mimetype[1])
            part.set_payload(attachment.content)
            encode_base64(part)
            part.add_header('Content-Disposition', 'attachment',
                            filename=attachment.name)
            msg.attach(part)

        return msg
Beispiel #11
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 #12
0
  def _execute(self, http, order, requests):
    """Serialize batch request, send to server, process response.

    Args:
      http: httplib2.Http, an http object to be used to make the request with.
      order: list, list of request ids in the order they were added to the
        batch.
      request: list, list of request objects to send.

    Raises:
      httplib2.HttpLib2Error if a transport error has occured.
      apiclient.errors.BatchError if the response is the wrong format.
    """
    message = MIMEMultipart('mixed')
    # Message should not write out it's own headers.
    setattr(message, '_write_headers', lambda self: None)

    # Add all the individual requests.
    for request_id in order:
      request = requests[request_id]

      msg = MIMENonMultipart('application', 'http')
      msg['Content-Transfer-Encoding'] = 'binary'
      msg['Content-ID'] = self._id_to_header(request_id)

      body = self._serialize_request(request)
      msg.set_payload(body)
      message.attach(msg)

    body = message.as_string()

    headers = {}
    headers['content-type'] = ('multipart/mixed; '
                               'boundary="%s"') % message.get_boundary()

    resp, content = http.request(self._batch_uri, 'POST', body=body,
                                 headers=headers)

    if resp.status >= 300:
      raise HttpError(resp, content, uri=self._batch_uri)

    # Now break out the individual responses and store each one.
    boundary, _ = content.split(None, 1)

    # Prepend with a content-type header so FeedParser can handle it.
    header = 'content-type: %s\r\n\r\n' % resp['content-type']
    for_parser = header + content

    parser = FeedParser()
    parser.feed(for_parser)
    mime_response = parser.close()

    if not mime_response.is_multipart():
      raise BatchError("Response not in multipart/mixed format.", resp=resp,
                       content=content)

    for part in mime_response.get_payload():
      request_id = self._header_to_id(part['Content-ID'])
      response, content = self._deserialize_response(part.get_payload())
      self._responses[request_id] = (response, content)
Beispiel #13
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 #14
0
    def send(self, event, message, response):
        msg = MIMEMultipart()

        if event.from_ in vbx.config.contacts:
            from_ = vbx.config.contacts[event.from_]
        else:
            from_ = event.from_

        msg['Subject'] = 'SMS From {}'.format(from_)
        msg['From'] = self.from_
        msg['To'] = self.to

        msg.attach(MIMEText(message))

        if event.media_url:
            main_type, sub_type = event.media_type.split('/', 1)
            part = MIMENonMultipart(main_type, sub_type)
            part.set_payload(urllib.request.urlopen(event.media_url).read())
            encoders.encode_base64(part)
            part[
                'Content-Disposition'] = 'attachment; filename="media.{}"'.format(
                    mimetypes.guess_extension(event.media_type))
            msg.attach(part)

        s = smtplib.SMTP('localhost')
        s.send_message(msg)
        s.quit()
Beispiel #15
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 #16
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 #17
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 #18
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 #19
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 #20
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 #21
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 #22
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 #23
0
 def _add_attachments(self, mime):
     for attachment in getattr(self, '_attachments', []):
         major, sub = attachment['content-type'].split('/')
         attachment_mime = MIMENonMultipart(major, sub)
         base64_attachment_file = binascii.b2a_base64(attachment['raw'])
         attachment_mime.set_payload(base64_attachment_file)
         attachment_mime['Content-Disposition'] = 'attachment; filename="%s"' % attachment['name']
         attachment_mime['Content-Transfer-Encoding'] = 'base64'
         mime.attach(attachment_mime)
Beispiel #24
0
 def _add_attachments(self, mime):
     for attachment in getattr(self, '_attachments', []):
         major, sub = attachment['content-type'].split('/')
         attachment_mime = MIMENonMultipart(major, sub)
         base64_attachment_file = binascii.b2a_base64(attachment['raw'])
         attachment_mime.set_payload(base64_attachment_file)
         attachment_mime['Content-Disposition'] = 'attachment; filename="%s"' % attachment['name']
         attachment_mime['Content-Transfer-Encoding'] = 'base64'
         mime.attach(attachment_mime)
Beispiel #25
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 #26
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 #27
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()
    def test_raw_with_attachment_data(self):
        input_mail = InputMail.from_dict(with_attachment_mail_dict(), from_address='pixelated@org')

        attachment = MIMENonMultipart('text', 'plain', Content_Disposition='attachment; filename=ayoyo.txt')
        attachment.set_payload('Hello World')
        mail = MIMEMultipart()
        mail.attach(attachment)

        part_one = 'Content-Type: text/plain\nMIME-Version: 1.0\nContent-Disposition: attachment; filename="ayoyo.txt"\nContent-Transfer-Encoding: base64\n\n'
        part_two = 'Content-Type: text/html\nMIME-Version: 1.0\nContent-Disposition: attachment; filename="hello.html"\nContent-Transfer-Encoding: base64\n\n'

        self.assertRegexpMatches(input_mail.raw, part_one)
        self.assertRegexpMatches(input_mail.raw, part_two)
    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 #31
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])
Beispiel #32
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 #33
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 #34
0
    def _serialize_request(self, request):
        """Convert an HttpRequest object into a string.

    Args:
      request: HttpRequest, the request to serialize.

    Returns:
      The request as a string in application/http format.
    """
        # Construct status line
        parsed = urlparse.urlparse(request.uri)
        request_line = urlparse.urlunparse(
            (None, None, parsed.path, parsed.params, parsed.query, None))
        status_line = request.method + ' ' + request_line + ' HTTP/1.1\n'
        major, minor = request.headers.get('content-type',
                                           'application/json').split('/')
        msg = MIMENonMultipart(major, minor)
        headers = request.headers.copy()

        if request.http is not None and hasattr(request.http.request,
                                                'credentials'):
            request.http.request.credentials.apply(headers)

        # MIMENonMultipart adds its own Content-Type header.
        if 'content-type' in headers:
            del headers['content-type']

        for key, value in headers.iteritems():
            msg[key] = value
        msg['Host'] = parsed.netloc
        msg.set_unixfrom(None)

        if request.body is not None:
            msg.set_payload(request.body)
            msg['content-length'] = str(len(request.body))

        # Serialize the mime message.
        fp = StringIO.StringIO()
        # maxheaderlen=0 means don't line wrap headers.
        g = Generator(fp, maxheaderlen=0)
        g.flatten(msg, unixfrom=False)
        body = fp.getvalue()

        # Strip off the \n\n that the MIME lib tacks onto the end of the payload.
        if request.body is None:
            body = body[:-2]

        return status_line.encode('utf-8') + body
Beispiel #35
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 #36
0
  def _serialize_request(self, request):
    """Convert an HttpRequest object into a string.

    Args:
      request: HttpRequest, the request to serialize.

    Returns:
      The request as a string in application/http format.
    """
    # Construct status line
    parsed = urlparse.urlparse(request.uri)
    request_line = urlparse.urlunparse(
        (None, None, parsed.path, parsed.params, parsed.query, None)
        )
    status_line = request.method + ' ' + request_line + ' HTTP/1.1\n'
    major, minor = request.headers.get('content-type', 'application/json').split('/')
    msg = MIMENonMultipart(major, minor)
    headers = request.headers.copy()

    if request.http is not None and hasattr(request.http.request,
        'credentials'):
      request.http.request.credentials.apply(headers)

    # MIMENonMultipart adds its own Content-Type header.
    if 'content-type' in headers:
      del headers['content-type']

    for key, value in headers.iteritems():
      msg[key] = value
    msg['Host'] = parsed.netloc
    msg.set_unixfrom(None)

    if request.body is not None:
      msg.set_payload(request.body)
      msg['content-length'] = str(len(request.body))

    # Serialize the mime message.
    fp = StringIO.StringIO()
    # maxheaderlen=0 means don't line wrap headers.
    g = Generator(fp, maxheaderlen=0)
    g.flatten(msg, unixfrom=False)
    body = fp.getvalue()

    # Strip off the \n\n that the MIME lib tacks onto the end of the payload.
    if request.body is None:
      body = body[:-2]

    return status_line.encode('utf-8') + body
        def _send_thread(sender, recipient, subject, message):
            MODULE.info('sending mail: thread running')

            msg = MIMENonMultipart('text', 'plain', charset='utf-8')
            cs = email.charset.Charset("utf-8")
            cs.body_encoding = email.charset.QP
            msg["Subject"] = subject
            msg["From"] = sender
            msg["To"] = recipient
            msg.set_payload(message, charset=cs)

            server = smtplib.SMTP('localhost')
            server.set_debuglevel(0)
            server.sendmail(sender, recipient, msg.as_string())
            server.quit()
            return True
Beispiel #38
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
    def test_raw_with_attachment_data(self):
        input_mail = InputMail.from_dict(with_attachment_mail_dict(),
                                         from_address='pixelated@org')

        attachment = MIMENonMultipart(
            'text',
            'plain',
            Content_Disposition='attachment; filename=ayoyo.txt')
        attachment.set_payload('Hello World')
        mail = MIMEMultipart()
        mail.attach(attachment)

        part_one = 'Content-Type: text/plain\nMIME-Version: 1.0\nContent-Disposition: attachment; filename="ayoyo.txt"\nContent-Transfer-Encoding: base64\n\n'
        part_two = 'Content-Type: text/html\nMIME-Version: 1.0\nContent-Disposition: attachment; filename="hello.html"\nContent-Transfer-Encoding: base64\n\n'

        self.assertRegexpMatches(input_mail.raw, part_one)
        self.assertRegexpMatches(input_mail.raw, part_two)
Beispiel #40
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()
    def send(self):
        path_ucr = self.ucr.get(
            "umc/self-service/passwordreset/email/text_file")
        if path_ucr and os.path.exists(path_ucr):
            path = path_ucr
        else:
            path = os.path.join(os.path.realpath(os.path.dirname(__file__)),
                                "email_body.txt")
        with open(path, "rb") as fp:
            txt = fp.read()

        fqdn = ".".join([self.ucr["hostname"], self.ucr["domainname"]])
        frontend_server = self.ucr.get(
            "umc/self-service/passwordreset/email/webserver_address", fqdn)
        link = "https://{fqdn}/univention/self-service/#page=newpassword".format(
            fqdn=frontend_server)
        tokenlink = "https://{fqdn}/univention/self-service/#page=newpassword&token={token}&username={username}".format(
            fqdn=frontend_server,
            username=urllib.quote(self.data["username"]),
            token=urllib.quote(self.data["token"]))

        txt = txt.format(username=self.data["username"],
                         token=self.data["token"],
                         link=link,
                         tokenlink=tokenlink)

        msg = MIMENonMultipart('text', 'plain', charset='utf-8')
        cs = email.charset.Charset("utf-8")
        cs.body_encoding = email.charset.QP
        msg["Subject"] = "Password reset"
        msg["Date"] = formatdate(localtime=True)
        msg["From"] = self.ucr.get(
            "umc/self-service/passwordreset/email/sender_address",
            "Password Reset Service <noreply@{}>".format(fqdn))
        msg["To"] = self.data["address"]
        msg.set_payload(txt, charset=cs)

        smtp = smtplib.SMTP(self.server)
        smtp.sendmail(msg["From"], self.data["address"], msg.as_string())
        smtp.quit()
        self.log("Sent mail with token to address {}.".format(
            self.data["address"]))

        return True
Beispiel #42
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 #43
0
    def mbox(self):
        from email.mime.nonmultipart import MIMENonMultipart
        from email.encoders import encode_7or8bit

        body = ''
        if self.description:
            body += self.description.content + '\n'
        body += self.content

        mbox = MIMENonMultipart('text', 'plain', charset='utf-8')

        mbox['Subject'] = ": ".join([t.name for t in self.tags] + [self.name.strip().capitalize()])
        mbox['From'] = '%s <%s>' % (self.submitter.name, self.submitter.email)
        mbox['Message-Id'] = self.msgid

        mbox.set_payload(body.encode('utf-8'))
        encode_7or8bit(mbox)

        return mbox.as_string()
Beispiel #44
0
    def mbox(self):
        from email.mime.nonmultipart import MIMENonMultipart
        from email.encoders import encode_7or8bit

        body = ''
        if self.comments[0].msgid == self.msgid:
            body += self.comments[0].content + '\n'
        body += self.content

        mbox = MIMENonMultipart('text', 'plain', charset='utf-8')

        mbox['Subject'] = self.name
        mbox['From'] = '%s <%s>' % (self.submitter.name, self.submitter.email)
        mbox['Message-Id'] = self.msgid

        mbox.set_payload(body.encode('utf-8'))
        encode_7or8bit(mbox)

        return mbox.as_string()
Beispiel #45
0
    def bind(self, param_values, **kw_param_values):
        """Bind the definition to parameter values, creating a document.

        :return: A 2-tuple (media_type, document).
        """
        definition = self.resolve_definition()
        params = definition.params(self.resource)
        validated_values = self.validate_param_values(params, param_values,
                                                      **kw_param_values)
        media_type = self.media_type
        if media_type == 'application/x-www-form-urlencoded':
            doc = urlencode(sorted(validated_values.items()))
        elif media_type == 'multipart/form-data':
            outer = MIMEMultipart()
            outer.set_type('multipart/form-data')
            missing = object()
            for param in params:
                value = validated_values.get(param.name, missing)
                if value is not missing:
                    if param.type == 'binary':
                        maintype, subtype = 'application', 'octet-stream'
                        params = {}
                    else:
                        maintype, subtype = 'text', 'plain'
                        params = {'charset': 'utf-8'}
                    inner = MIMENonMultipart(maintype, subtype, **params)
                    inner.set_payload(value)
                    inner['Content-Disposition'] = ('form-data; name="%s"' %
                                                    param.name)
                    outer.attach(inner)
            doc = str(outer)
            # Chop off the 'From' line, which only makes sense in an
            # email.  (Python 3 does not include it.)
            if doc.startswith('From '):
                doc = doc[doc.find('\n') + 1:]
            media_type = (outer.get_content_type() +
                          '; boundary="%s"' % outer.get_boundary())
        elif media_type == 'application/json':
            doc = json.dumps(validated_values)
        else:
            raise ValueError("Unsupported media type: '%s'" % media_type)
        return media_type, doc
Beispiel #46
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'])
    def bind(self, param_values, **kw_param_values):
        """Bind the definition to parameter values, creating a document.

        :return: A 2-tuple (media_type, document).
        """
        definition = self.resolve_definition()
        params = definition.params(self.resource)
        validated_values = self.validate_param_values(
            params, param_values, **kw_param_values)
        media_type = self.media_type
        if media_type == 'application/x-www-form-urlencoded':
            doc = urlencode(sorted(validated_values.items()))
        elif media_type == 'multipart/form-data':
            outer = MIMEMultipart()
            outer.set_type('multipart/form-data')
            missing = object()
            for param in params:
                value = validated_values.get(param.name, missing)
                if value is not missing:
                    if param.type == 'binary':
                        maintype, subtype = 'application', 'octet-stream'
                        params = {}
                    else:
                        maintype, subtype = 'text', 'plain'
                        params = {'charset' : 'utf-8'}
                    inner = MIMENonMultipart(maintype, subtype, **params)
                    inner.set_payload(value)
                    inner['Content-Disposition'] = (
                        'form-data; name="%s"' % param.name)
                    outer.attach(inner)
            doc = str(outer)
            # Chop off the 'From' line, which only makes sense in an
            # email.  (Python 3 does not include it.)
            if doc.startswith('From '):
                doc = doc[doc.find('\n')+1:]
            media_type = (outer.get_content_type() +
                          '; boundary="%s"' % outer.get_boundary())
        elif media_type == 'application/json':
            doc = json.dumps(validated_values)
        else:
            raise ValueError("Unsupported media type: '%s'" % media_type)
        return media_type, doc
Beispiel #48
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 #49
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 #50
0
    def get_attachments(self):
        attachments = []

        # attach files
        for data, content_type, filename, disposition in \
                self.context.get_attachments():
            maintype, subtype = content_type.split('/')

            msg = MIMENonMultipart(maintype, subtype)

            msg.set_payload(data)
            if filename:
                msg['Content-Id']=bytes_('<{0}@ptah>'.format(filename),'utf-8')
                msg['Content-Disposition']=bytes_('{0}; filename="{1}"'.format(
                    disposition, filename), 'utf-8')

            encoders.encode_base64(msg)
            attachments.append(msg)

        return attachments
Beispiel #51
0
    async def _serialize_request(self, request):
        """
        Convert an HttpRequest object into a string.

        Args:
          request: HttpRequest, the request to serialize.

        Returns:
          The request as a string in application/http format.
        """
        parsed = urlparse(request.uri)
        request_line = urlunparse(
            ("", "", parsed.path, parsed.params, parsed.query, ""))
        status_line = request.method + " " + request_line + " HTTP/1.1\n"
        major, minor = request.headers.get("content-type",
                                           "application/json").split("/")
        msg = MIMENonMultipart(major, minor)
        headers = request.headers.copy()

        # MIMENonMultipart adds its own Content-Type header.
        if "content-type" in headers:
            del headers["content-type"]

        for key, value in headers.items():
            msg[key] = value
        msg["Host"] = parsed.netloc
        msg.set_unixfrom(None)

        if request.body is not None:
            msg.set_payload(request.body)
            msg["content-length"] = str(len(request.body))

        # Serialize the mime message.
        fp = StringIO()
        # maxheaderlen=0 means don't line wrap headers.
        g = Generator(fp, maxheaderlen=0)
        g.flatten(msg, unixfrom=False)
        body = fp.getvalue()

        return status_line + body
Beispiel #52
0
  def _serialize_request(self, request):
    """Convert an HttpRequest object into a string.

    Args:
      request: HttpRequest, the request to serialize.

    Returns:
      The request as a string in application/http format.
    """
    # Construct status line
    parsed = urlparse.urlparse(request.uri)
    request_line = urlparse.urlunparse(
        (None, None, parsed.path, parsed.params, parsed.query, None)
        )
    status_line = request.method + ' ' + request_line + ' HTTP/1.1\n'
    major, minor = request.headers.get('content-type', 'application/json').split('/')
    msg = MIMENonMultipart(major, minor)
    headers = request.headers.copy()

    # MIMENonMultipart adds its own Content-Type header.
    if 'content-type' in headers:
      del headers['content-type']

    for key, value in headers.iteritems():
      msg[key] = value
    msg['Host'] = parsed.netloc
    msg.set_unixfrom(None)

    if request.body is not None:
      msg.set_payload(request.body)
      msg['content-length'] = str(len(request.body))

    body = msg.as_string(False)
    # Strip off the \n\n that the MIME lib tacks onto the end of the payload.
    if request.body is None:
      body = body[:-2]

    return status_line.encode('utf-8') + body
Beispiel #53
0
 def addAttachment(self, attachment, filename, mimetype=None):
     "Attaches the given file to this message."
     # Figure out the major and minor MIME type of this attachment,
     # given its filename.
     if not mimetype:
         mimetype = mimetypes.guess_type(filename)[0]
     if not mimetype:
         raise Exception("Couldn't determine MIME type for ", filename)
     if "/" in mimetype:
         major, minor = mimetype.split("/")
     else:
         major = mimetype
         minor = None
     # The message was constructed under the assumption that it was
     # a single-part message. Now that we know there's to be at
     # least one attachment, we need to change it into a multi-part
     # message, with the first part being the body of the message.
     if not self.hasAttachments:
         body = self.msg.get_payload()
         newMsg = MIMEMultipart()
         newMsg.attach(MIMEText(body))
         # Copy over the old headers to the new object.
         for header, value in self.msg.items():
             newMsg[header] = value
         self.msg = newMsg
         self.hasAttachments = True
     subMessage = MIMENonMultipart(major, minor, name=filename)
     subMessage.set_payload(attachment)
     # Encode text attachments as quoted-printable, and all other
     # types as base64.
     if major == "text":
         encoder = Encoders.encode_quopri
     else:
         encoder = Encoders.encode_base64
     encoder(subMessage)
     # Link the MIME message part with its parent message.
     self.msg.attach(subMessage)
Beispiel #54
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 #55
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 #56
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 #57
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)
  def method(self, **kwargs):
    # Don't bother with doc string, it will be over-written by createMethod.

    for name in kwargs.iterkeys():
      if name not in parameters.argmap:
        raise TypeError('Got an unexpected keyword argument "%s"' % name)

    # Remove args that have a value of None.
    keys = kwargs.keys()
    for name in keys:
      if kwargs[name] is None:
        del kwargs[name]

    for name in parameters.required_params:
      if name not in kwargs:
        raise TypeError('Missing required parameter "%s"' % name)

    for name, regex in parameters.pattern_params.iteritems():
      if name in kwargs:
        if isinstance(kwargs[name], basestring):
          pvalues = [kwargs[name]]
        else:
          pvalues = kwargs[name]
        for pvalue in pvalues:
          if re.match(regex, pvalue) is None:
            raise TypeError(
                'Parameter "%s" value "%s" does not match the pattern "%s"' %
                (name, pvalue, regex))

    for name, enums in parameters.enum_params.iteritems():
      if name in kwargs:
        # We need to handle the case of a repeated enum
        # name differently, since we want to handle both
        # arg='value' and arg=['value1', 'value2']
        if (name in parameters.repeated_params and
            not isinstance(kwargs[name], basestring)):
          values = kwargs[name]
        else:
          values = [kwargs[name]]
        for value in values:
          if value not in enums:
            raise TypeError(
                'Parameter "%s" value "%s" is not an allowed value in "%s"' %
                (name, value, str(enums)))

    actual_query_params = {}
    actual_path_params = {}
    for key, value in kwargs.iteritems():
      to_type = parameters.param_types.get(key, 'string')
      # For repeated parameters we cast each member of the list.
      if key in parameters.repeated_params and type(value) == type([]):
        cast_value = [_cast(x, to_type) for x in value]
      else:
        cast_value = _cast(value, to_type)
      if key in parameters.query_params:
        actual_query_params[parameters.argmap[key]] = cast_value
      if key in parameters.path_params:
        actual_path_params[parameters.argmap[key]] = cast_value
    body_value = kwargs.get('body', None)
    media_filename = kwargs.get('media_body', None)

    if self._developerKey:
      actual_query_params['key'] = self._developerKey

    model = self._model
    if methodName.endswith('_media'):
      model = MediaModel()
    elif 'response' not in methodDesc:
      model = RawModel()

    headers = {}
    headers, params, query, body = model.request(headers,
        actual_path_params, actual_query_params, body_value)

    expanded_url = uritemplate.expand(pathUrl, params)
    url = urlparse.urljoin(self._baseUrl, expanded_url + query)

    resumable = None
    multipart_boundary = ''

    if media_filename:
      # Ensure we end up with a valid MediaUpload object.
      if isinstance(media_filename, basestring):
        (media_mime_type, encoding) = mimetypes.guess_type(media_filename)
        if media_mime_type is None:
          raise UnknownFileType(media_filename)
        if not mimeparse.best_match([media_mime_type], ','.join(accept)):
          raise UnacceptableMimeTypeError(media_mime_type)
        media_upload = MediaFileUpload(media_filename,
                                       mimetype=media_mime_type)
      elif isinstance(media_filename, MediaUpload):
        media_upload = media_filename
      else:
        raise TypeError('media_filename must be str or MediaUpload.')

      # Check the maxSize
      if maxSize > 0 and media_upload.size() > maxSize:
        raise MediaUploadSizeError("Media larger than: %s" % maxSize)

      # Use the media path uri for media uploads
      expanded_url = uritemplate.expand(mediaPathUrl, params)
      url = urlparse.urljoin(self._baseUrl, expanded_url + query)
      if media_upload.resumable():
        url = _add_query_parameter(url, 'uploadType', 'resumable')

      if media_upload.resumable():
        # This is all we need to do for resumable, if the body exists it gets
        # sent in the first request, otherwise an empty body is sent.
        resumable = media_upload
      else:
        # A non-resumable upload
        if body is None:
          # This is a simple media upload
          headers['content-type'] = media_upload.mimetype()
          body = media_upload.getbytes(0, media_upload.size())
          url = _add_query_parameter(url, 'uploadType', 'media')
        else:
          # This is a multipart/related upload.
          msgRoot = MIMEMultipart('related')
          # msgRoot should not write out it's own headers
          setattr(msgRoot, '_write_headers', lambda self: None)

          # attach the body as one part
          msg = MIMENonMultipart(*headers['content-type'].split('/'))
          msg.set_payload(body)
          msgRoot.attach(msg)

          # attach the media as the second part
          msg = MIMENonMultipart(*media_upload.mimetype().split('/'))
          msg['Content-Transfer-Encoding'] = 'binary'

          payload = media_upload.getbytes(0, media_upload.size())
          msg.set_payload(payload)
          msgRoot.attach(msg)
          body = msgRoot.as_string()

          multipart_boundary = msgRoot.get_boundary()
          headers['content-type'] = ('multipart/related; '
                                     'boundary="%s"') % multipart_boundary
          url = _add_query_parameter(url, 'uploadType', 'multipart')

    logger.info('URL being requested: %s %s' % (httpMethod,url))
    return self._requestBuilder(self._http,
                                model.response,
                                url,
                                method=httpMethod,
                                body=body,
                                headers=headers,
                                methodId=methodId,
                                resumable=resumable)