지난 글에 이어 이 글에서는 첨부파일을 포함한 메일을 전송할 수 있는 코드를 다룬다.
마찬가지로 코드 전체를 복사해서 사용한다면, MAIN 아래의 email_sender부터 attachment_filepath까지의 값을 잘 넣어주면 된다.
전체 코드
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
import os
import time
class MailSender:
def __init__(self, email_sender, sender_passwd, email_recipient, email_server, email_server_port):
self.msg = MIMEMultipart()
self.sender = email_sender
self.passwd = sender_passwd
self.recipient = email_recipient
self.email_server = email_server
self.email_server_port = email_server_port
self.subject = ""
self.body = ""
def context(self, subject, body):
self.subject = subject
self.body = body
def attachment(self, exist_attachment, attachment_filepath):
if exist_attachment:
attachment = open(attachment_filepath, 'rb')
part = MIMEBase('application', 'octet-stream')
part.set_payload((attachment).read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', "attachment", filename=os.path.basename(attachment_filepath))
self.msg.attach(part)
def write(self, exist_attachment, attachment_filepath):
self.msg['From'] = self.sender
self.msg['To'] = self.recipient
self.msg['Subject'] = self.subject
self.msg.attach(MIMEText(self.body, 'plain'))
self.attachment(exist_attachment, attachment_filepath)
def send(self):
server = smtplib.SMTP(self.email_server, self.email_server_port)
server.ehlo()
server.starttls()
server.login(self.sender, self.passwd)
server.sendmail(self.sender, self.recipient, self.msg.as_string())
server.quit()
#################### MAIN ####################
# sender/recipient info
email_sender = '보내는 사람 메일 주소'
sender_passwd = '메일 서버 접속에 사용하는 비밀번호'
email_recipient = '받는 사람 메일 주소'
email_server = '메일 서버 주소'
email_server_port = 587 # 메일 서버 접속에 사용하는 포트
# mail context
subject = "제목"
body = "내용"
# attachment info
exist_attachment = True
attachment_filepath = '파일 경로'
# init Mail essentail info
mail = MailSender(email_sender, sender_passwd, email_recipient, email_server, email_server_port)
# writing subject/body of mail
mail.context(subject, body)
mail.write(exist_attachment, attachment_filepath)
# sending mail
mail.send()
아래에는 MailSender 클래스에서 텍스트 파일 전송 코드와 다른 부분에 대해서만 적어둔다.
달라진 게 있긴 한가
1. import 부분
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase # MIME 클래스의 부모 클래스
from email import encoders # 이진 파일을 텍스트로 인코딩
import os
import time
첨부파일을 처리하기 위한 모듈을 import 한다.
2. attachment 함수
def attachment(self, exist_attachment, attachment_filepath):
if exist_attachment:
attachment = open(attachment_filepath, 'rb') # 첨부 파일 열기
part = MIMEBase('application', 'octet-stream')
part.set_payload((attachment).read()) # 첨부 파일 읽기
encoders.encode_base64(part) # 텍스트로 인코딩
part.add_header('Content-Disposition', "attachment", filename=os.path.basename(attachment_filepath)) # 헤더 속성 명시
self.msg.attach(part) # 파일 첨부
첨부 파일 전송 여부와 파일 경로를 매개변수로 받아, 첨부 파일을 전송할 경우에만 첨부 파일 처리를 진행하는 함수다.
MIMEBase는 인스턴스 생성 시 내용 포맷/내용 형식(maintype/subtype)을 지정하는데, application/octet-stream은 이진 파일을 보낼 때 사용한다. 어떤 파일이든 이진 파일이면 첨부할 수 있다.
3. write 함수
def write(self, exist_attachment, attachment_filepath):
self.msg['From'] = self.sender
self.msg['To'] = self.recipient
self.msg['Subject'] = self.subject
self.msg.attach(MIMEText(self.body, 'plain'))
self.attachment(exist_attachment, attachment_filepath)
기존과 달리 첨부 파일 전송 여부와 파일 경로를 매개변수로 받는다.
파일 첨부도 msg 객체에 처리가 들어가기 때문에 msg 객체의 값을 초기화하는 write 함수에서 attachment 함수를 호출하게 하였다.
이 외의 코드는 동일하다.
코드 수정 시 수정 부분을 줄이고, main 부분을 간결하게 작성해보자 싶어서, 오랜만에 코드를 만져봤는데…… 목적은 달성했지만 좀 엉망으로 나온 것 같다.
python으로 클래스는 어떻게 작성하는지에 대해 전혀 공부를 안 하고 진행한 탓인 듯?
다들 파이썬 쉽댔는데…… 난 왜 어렵지……?