IMAP을 통한 메일 확인

2019. 4. 21. 21:20파이썬

*메일 읽어오기(imaplib 모듈)
#IMAP 서버 접속
import imaplib
imap = imaplib.IMAP4_SSL('imap.gmail.com')

#IMAP 서버 로그인
imap.login('userid@gmail.com', 'password')

#INBOX 선택
imap.select('inbox') #(결과, 읽지 않은 메시지)

#이메일 검색 : 각 메일에는 UID가 있다
#명령 : 검색(여기서는 전체),리턴은 결과와 데이터
result, data = imap.uid('search', None, "ALL")
#가장 마지막 uid
latest_email_uid = data[0].split()[-1]
#fetch 명령을 통해서 메일을 가져온다
result, data = imap.uid('fetch', latest_email_uid, '(RFC822)')
#사람이 읽기 힘든 날 것의 메세지
raw_email = data[0][1]

*메일 파싱하기(email 모듈)
import email
email_message = email.message_from_string(raw_email.decode('utf-8'))
print(email_message['To'])
print(email.utils.parseaddr(email_message['From']))

#이메일 본문 내용 확인
if email_message.is_multipart():
    for p in email_message.get_payload():
        print(p.get_payload())

imap.close()
imap.logout()

*메일 읽어오기(imaplib 모듈)
#IMAP 서버 접속
import imaplib
imap = imaplib.IMAP4_SSL('imap.gmail.com')

#IMAP 서버 로그인
imap.login('userid@gmail.com', 'password')

#INBOX 선택
imap.select('inbox') #(결과, 읽지 않은 메시지)

#이메일 검색 : 각 메일에는 UID가 있다
#명령 : 검색(여기서는 전체),리턴은 결과와 데이터
result, data = imap.uid('search', None, "ALL")
#가장 마지막 uid
latest_email_uid = data[0].split()[-1]
#fetch 명령을 통해서 메일을 가져온다
result, data = imap.uid('fetch', latest_email_uid, '(RFC822)')
#사람이 읽기 힘든 날 것의 메세지
raw_email = data[0][1]

*메일 파싱하기(email 모듈)
import email
#바이너리를 utf-8 문자열로
email_message = email.message_from_string(raw_email.decode('utf-8'))
print(email_message['To'])
print(email.utils.parseaddr(email_message['From']))

#이메일 본문 내용 확인
if email_message.is_multipart():
    for p in email_message.get_payload():
        print(p.get_payload())

imap.close()
imap.logout()


#이메일 지우기(지울 메세지의 uid)
imap.uid('store', '65334', '+FLAGS', '(\\Deleted)')
imap.expunge()#메일함 정리하기
#출력 ('OK', [b'2'])일 때 2번 메일이 지워졌다는 의미








*메일 읽어오기(imaplib 모듈)
#IMAP 서버 접속
import imaplib
imap = imaplib.IMAP4_SSL('imap.gmail.com')

#IMAP 서버 로그인
imap.login('userid@gmail.com', 'password')

#INBOX 선택
imap.select('inbox') #(결과, 읽지 않은 메시지)

#이메일 검색 : 각 메일에는 UID가 있다
#명령 : 검색(여기서는 전체),리턴은 결과와 데이터
result, data = imap.uid('search', None, "ALL")
#imap.uid('search', None, '(HEADER Subject "instruction")')#제목이 instruction인 메세지만 찾아온다
#imap.uid('search', None, '(HEADER From "userid@gmail")')#보낸 사람이 userid@gmail인 놈으로 찾기
#date = (datetime.date.today() - datetime.timedelta(1)).strftime("%Y-%m-%d")
#result, data = mail.uid('search', None, '(SENTSINCE {})'.format(date))#특정 날짜 이후로 찾기


#가장 마지막 uid
latest_email_uid = data[0].split()[-1]
#fetch 명령을 통해서 메일을 가져온다
result, data = imap.uid('fetch', latest_email_uid, '(RFC822)')
#사람이 읽기 힘든 날 것의 메세지
raw_email = data[0][1]

*메일 파싱하기(email 모듈)
import email
#바이너리를 utf-8 문자열로
email_message = email.message_from_string(raw_email.decode('utf-8'))
print(email_message['To'])
print(email.utils.parseaddr(email_message['From']))

#이메일 본문 내용 확인
if email_message.is_multipart():
    for p in email_message.get_payload():
        print(p.get_payload())

imap.close()
imap.logout()


#이메일 지우기(지울 메세지의 uid)
imap.uid('store', '65334', '+FLAGS', '(\\Deleted)')
imap.expunge()#메일함 정리하기
#출력 ('OK', [b'2'])일 때 2번 메일이 지워졌다는 의미


#이메일 찾기(search 함수)
#1) header로 찾기
imap.uid('search', None, '(HEADER Subject "instruction")') #제목
imap.uid('search', None, '(HEADER From "uid@gmail.com")') #보낸사람

#2) 특정 날짜 이후로 찾기
import datetime
date = (datetime.date.today() - datetime.timedelta(1)).strftime("%Y-%m-%d")
result, data = mail.uid('search', None, '(SENTSINCE {})'.format(date))


#토렌트 파일의 이름을 이메일로 보내면
#주기적으로 메일을 체크하는 파이썬 데몬이 메일을 읽어
#토렌트를 자동으로 다운로드 하는 프로그램
#1) 매 15분마다 메일을 체크하는 데몬 작성
#2) 해당 메일이 있으면 토렌트 파일명을 가져온다.
#3) Popen()로 토렌트를 실행시킨다.
#   gbProcess = subprocess.Popen(['c:\\program files (x86)\\qBittorrent\\qbittorrent.exe', 'shakepare_complete_works.torrent'])
#4) 작업 완료 후 완료 메일을 보낸다.


MY_EMAIL = 'asweigart@gmail.com'
BOT_EMAIL = 'imaptest@coffeeghost.net'
BOT_EMAIL_PASSWORD = 'PASSWORD'
TORRENT_PROGRAM = 'c:\\Program Files (x86)\\qBittorrent\\qbittorrent.exe'
SMTP_SERVER = 'smtp.gmail.com'
SMTP_PORT = 465

def check_and_get_instruction_email():
    #로그인 imap
    logging.debug('Connectiong to IMAP server..')
    imap = imaplib.IMAP4_SSL('imap.gmail.com')
    imap.login(BOT_EMAIL, BOT_EMAIL_PASSWORD)
    logging.debug('Connected.')
    
    result, data = imap.select('inbox')
    
    #명령관련 모든 메일을 가져온다.
    instruction = []
    
    #메일이 없으면 비 배열 리턴
    if data[0].decode('utf-8') == '0':
        logging.debug('No mail founded..')
        return instructions
    
    result, data = imap.uid('search', None, '(HEADER Subject "instruction")')
    uids = data[0].split()
    
    for target_uid in inds:
        result, dat = imap.uid('fetch', target_uid, '(RFC822)')
        raw_message = data[0][1]
        email_message = email.message_from_string(raw_message.decode('utf-8'))
        
        #메일에서 본문을 추출한다.
        if email_message.is_multipart():
            payload = email_message.get_payload()[0]
            instructions.append(payload.get_payload().strip())
        else:
            instruction.append(email_message.get_payload().strip())
        
        #명령어를 추출한 이메일은 삭제한다.
        imap.uid('store', target_uid, '+FLAGS', '(\\Deleted)')
        imap.expunge()
    
    #로그아웃
imap.close()
    imap.logout()
    return instructions:
    
def do_instruction(instruction):
    #명령어를 분석하여 처리한다.
    subprocess.Popen(TORRENT_PROGRAM + ' ' + instruction)#토렌트 프로그램 수행
    #작업내용 메일 메세지를 작성한다.
    msg = EmailMessage()
    msg['Subject'] = '작업완료 내용'
    msg['From'] = BOT_EMAIL
    msg['To'] = recipient@mail.co.kr
    msg.set_content('''
    다음과 같이 작업이 새행되었습니다.
    {}{}
    좋은하루 되세요.
    '''.format(TORRENT_PROGRAM, instruction))
    
    #작업 수행 후 작업 내용 메일을 보낸다.
    logging.debug('Connecting to SMTP server at {} to send confirmation email...'.format(SMTP_SERVER))
smtp = smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT)
    smtp.ehlo()
smtp.loging(BOT_EMAIL, BOT_EMAIL_PASSWORD)
logging.debug('Connected')
smtp.send_message(msg)
LOGGING.DEBUG('confirmation email sent.')
smtp.quit()




def main():
    #매 15분마다 메일을 체크하며 무한루프를 돈다.
    print('Email bot started. Press Ctrl-C to quit.')
    logging.debug('Email bot started.')
    
    while True:
        try:#메일의 내용에 명령이 있다.
            logging.debug('Getting instruction from email....')
            instruction = check_and_get_instruction_email()
            
            for instruction in instructions:
                logging.debug('Doing instruction : ' + instruction)
                do_instruction(instruction)
        except Exception as err:
            logging.error(err)