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)
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()
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)
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)
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)
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()
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
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()
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
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()
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)
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()
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()
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)
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
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
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()
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')
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, })
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
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]
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)
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()
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()
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 send_report(self, date, short_description, additional_description, title, _filename): full_email = MIMEMultipart('mixed') full_email['Subject'] = date + " " + self.subject full_email['From'] = self.sender full_email['To'] = self.receipant email_addresses = self.receipant.split(',') # CSV FILE attachment = MIMENonMultipart('plain', 'csv', charset='utf-8') attachment.add_header('Content-Disposition', 'attachment', filename=_filename[39:len(_filename)]) attachment.set_payload(open(_filename, "rb").read()) full_email.attach(attachment) # HTML TABLE body = MIMEMultipart('alternative') body.attach( MIMEText( (short_description + additional_description).encode('utf-8'), 'html', _charset='utf-8')) body.attach( MIMEText(("""\ <html> <head></head> <body> <div style="text-align:center"> <strong> <h1><font color="red">""" + title + """</font></h1> <h4>""" + short_description + additional_description + """</h4> </strong> </div> </body> </html> """).encode('utf-8'), 'html', _charset='utf-8')) full_email.attach(body) s = smtplib.SMTP(self.server, self.port) if self.tls == 'yes': s.starttls() if not self.login == '': s.login(self.login, self.password) try: s.sendmail(self.sender, email_addresses, full_email.as_string()) s.quit() except SMTPException as e: print "ERROR %d: %s" % (e.args[0], e.args[1])
def _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
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
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 _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()
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
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)
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
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
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()
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()
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
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
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
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
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
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
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)
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
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)
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)