파이썬 프로젝트 및 응용/몸이불편한 분들을 위한 음성 이메일 보내기

[프로젝트] 파이썬 몸이불편한 분들을 위한 음성 이메일 보내기 - 4.음성으로 이메일 보내기 - 본문편

파기차차 2023. 6. 24. 15:14
728x90
반응형
SMALL

ㅁ 개요

 

O 프로그램 소개

 

 

- 이번 글은 이전글([프로젝트] 파이썬 몸이불편한 분들을 위한 음성 이메일 보내기 - 3.음성으로 이메일 보내기 - 제목편)에 이은 5번째 글로 음성으로 메일을 보내기 위해 세번째로 본문을 작성하는 방법에 대하여 살펴보겠습니다.

 

 

 

O 완성된 프로그램 실행 화면

 

 

 - 본 포스팅의 최종 완성된 프로그램의 결과화면은 아래와 같습니다.

 

 

1.프로그램을 실행하면 아래와 같이 실행 되며, 메일 본문 내용을 말하면 한 줄씩 저장되고, 추가 내용을 입력할지 물어봅니다.

추가입력하는 경우 추가입력 후 내용이 맞는지 확인 후 추가 입력이 없으면 종료됩니다.

 

 

 

 

 

 


 

ㅁ 세부 내용

 

O 완성된 소스

 

 

소스 : 4.py

 

# -*- coding: utf-8 -*-
import smtplib
from email.encoders import encode_base64
from email.header import Header
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import formatdate
import os
import re

import speech_recognition as sr
from gtts import gTTS
import os
import playsound
from translate import Translator

from config import *
emailpw = EMAILPW



def textToVoice(text):
    tts = gTTS(text=text, lang='ko')
    filename='voice.mp3'
    tts.save(filename) # 파일을 만들고,
    playsound.playsound(filename) # 해당 음성파일을 실행(즉, 음성을 말함)
    os.remove(filename)

def voiceToText():
    r = sr.Recognizer()
    with sr.Microphone() as source:
        print("say something: ")
        audio = r.listen(source)
        said = " "

        try:
            said = r.recognize_google(audio, language="ko-KR")
            print("Your speech thinks like: ", said)
        except Exception as e:
            print("Exception: " + str(e))
    
    return said

def send_email():
    ################################################################
    # 2. 이메일 발송
    ################################################################
    msg = MIMEMultipart()

    emailList = 'pygichacha@gmail.com,secuhelper@naver.com'
    emailTitle = '음성 메일보내기 테스트'
    emailContent = '음성 메일보내기 테스트 입니다.'

    msg['From'] = 'secuhelper@naver.com'
    msg['To'] = emailList
    msg['Date'] = formatdate(localtime=True)
    msg['Subject'] = Header(s=emailTitle, charset='utf-8')
    body = MIMEText(emailContent, _charset='utf-8')
    msg.attach(body)

    mailServer = smtplib.SMTP_SSL('smtp.naver.com')

    debugMessage = mailServer.set_debuglevel(True)
    print(debugMessage, type(debugMessage)) # 디버그 메시지에 'retcode (221)' 가 포함되어 있으면 정상 발송한 것임

    mailServer.login('secuhelper@naver.com', emailpw)  # 본인 계정과 비밀번호 사용.
    mailServer.send_message(msg)
    mailServer.quit()



def input_email_recipients():
    global email_recipients,for_break
    print("이메일을 받는 사람의 이름을 알려주세요.")
    textToVoice("이메일을 받는 사람의 이름을 알려주세요.")
    my_res = voiceToText()

    for key in  emaildic.keys():
        print(key,"++++++++++++++++++++++++++++++++++++++")
        if key in my_res:
       # if "홍길동" in my_res:
            print("이메일을 받는 사람이 "+key+" 이 맞습니까? 맞으면 yes, 아니면 no로 대답해 주세요.")
            textToVoice("이메일을 받는 사람이 "+key+" 이 맞습니까? 맞으면 yes, 아니면 no로 대답해 주세요.")
            my_res2 = voiceToText()

            if my_res2 == "yes" or my_res2 == "예스":
                print("이메일을 받는사람에 "+key+" 로 저장하고, 이메일 제목 단계로 이동 합니다.")
                textToVoice("이메일을 받는사람에 "+key+" 로 저장하고, 이메일 제목 단계로 이동 합니다.")
                email_recipients = key
                for_break = False
                break
            else:
                print("이메일을 받는사람이 잘못 지정되었습니다. 다시 입력합니다.")
                textToVoice("이메일을 받는사람이 잘못 지정되었습니다. 다시 입력합니다.")
                input_email_recipients()


def input_email_title():
    global email_title

    print("이메일 제목을 알려주세요.")
    textToVoice("이메일 제목을 알려주세요.")
    my_res = voiceToText()

    if '굿바이' in my_res:
        print("음성 이메일 시스템을 종료합니다.")
        textToVoice("음성 이메일 시스템을 종료합니다.")

    print("이메일 제목이 "+my_res+" 이 맞습니까? 맞으면 yes, 아니면 no로 대답해 주세요.")
    textToVoice("이메일 제목이 "+my_res+" 이 맞습니까? 맞으면 yes, 아니면 no로 대답해 주세요.")
    my_res2 = voiceToText()

    if my_res2 == "yes" or my_res2 == "예스":
        print("이메일 제목을 "+my_res+" 로 저장하고, 이메일 본문 작성 단계로 이동 합니다.")
        textToVoice("이메일 제목을 "+my_res+" 로 저장하고, 이메일 본문 작성 단계로 이동 합니다.")
        email_title = my_res
    else:
        print("이메일 제목이 잘못 지정되었습니다. 다시 입력합니다.")
        textToVoice("이메일 제목이 잘못 지정되었습니다. 다시 입력합니다.")
        input_email_title()



def input_email_contents():
    global email_contents,for_break

    print("이메일 본문 내용은 한 줄씩 입력합니다. 본문내용을 알려주세요.")
    textToVoice("이메일 본문 내용은 한 줄씩 입력합니다. 본문내용을 알려주세요.")
    my_res = voiceToText()+"\n\n"

    if '굿바이' in my_res:
        print("음성 이메일 시스템을 종료합니다.")
        textToVoice("음성 이메일 시스템을 종료합니다.")

    # 본문: 음성으로 이메일 보내기입니다.
    # 몸이 불편하거나 연세가 많으신 분들을 위한 시스템입니다.
    print("조금전 말씀하신 이메일 본문내용이 "+my_res+" 가 맞습니까? 맞으면 yes, 아니면 no로 대답해 주세요.")
    textToVoice("조금전 말씀하신 이메일 본문내용이 "+my_res+" 가 맞습니까? 맞으면 yes, 아니면 no로 대답해 주세요.")
    my_res2 = voiceToText()

    if my_res2 == "yes" or my_res2 == "예스":
        print("조금전 말씀하신 이메일 본문내용을 저장하였습니다.")
        textToVoice("조금전 말씀하신 이메일 본문내용을 저장하였습니다.")
        email_contents = str(email_contents) + my_res
        # break

        print("추가 입력 하겠습니까? 추가 입력하려면 yes, 아니면 no로 대답해 주세요.")
        textToVoice("추가 입력 하겠습니까? 추가 입력하려면 yes, 아니면 no로 대답해 주세요.")
        my_res3 = voiceToText()
        
        if my_res3 == "yes" or my_res3 == "예스":
            input_email_contents()
        else:
            print("전체 본문내용은 다음과 같습니다.")
            textToVoice("전체 본문내용은 다음과 같습니다.")
            print(email_contents)
            textToVoice(email_contents)

            print("본문내용 입력을 종료합니다.")
            textToVoice("본문내용 입력을 종료합니다.")
            for_break = False

    else:
        print("이메일 본문내용이 잘못 입력되었습니다. 다시 입력 하겠습니다.")
        textToVoice("이메일 본문내용이 잘못 입력되었습니다. 다시 입력 하겠습니다.")
        input_email_contents()




emaildic = {'홍길동':'pygichacha@gmail.com','백두산':'secuhelper@naver.com'}





# ######################## 1.이메일 수신자 받기 시작 ########################

# email_recipients = False #이메일 수신자가 처음엔 지징되어 있지않음
# for_break = True 

# while True:

#     if email_recipients: #이메일 수신자가 지징되어 있으면 루프를 빠져나옴
#         break

#     if for_break == False: # 이중 루프를 빠져나가기 위한 변수 설정임
#         break

#     print("이메일 시스템을 종료하려면 '굿바이'라고 말씀해 주세요.")
#     textToVoice("이메일 시스템을 종료하려면 '굿바이'라고 말씀해 주세요.")

#     print("이메일을 받는 사람의 이름을 알려주세요.")
#     textToVoice("이메일을 받는 사람의 이름을 알려주세요.")
#     my_res = voiceToText()

#     if '굿바이' in my_res:
#         print("음성 이메일 시스템을 종료합니다.")
#         textToVoice("음성 이메일 시스템을 종료합니다.")
#         break

#     for key in  emaildic.keys():
#         if '굿바이' in my_res:
#             print("음성 이메일 시스템을 종료합니다.2")
#             textToVoice("음성 이메일 시스템을 종료합니다.2")
#             for_break = False
#             break

#         print(key,"++++++++++++++++++++++++++++++++++++++")
#         if key in my_res:
#        # if "홍길동" in my_res:
#             print("이메일을 받는 사람이 "+key+" 이 맞습니까? 맞으면 yes, 아니면 no로 대답해 주세요.")
#             textToVoice("이메일을 받는 사람이 "+key+" 이 맞습니까? 맞으면 yes, 아니면 no로 대답해 주세요.")
#             my_res2 = voiceToText()

#             if my_res2 == "yes" or my_res2 == "예스":
#                 print("이메일을 받는사람에 "+key+" 로 저장하고, 이메일 제목 단계로 이동 합니다.")
#                 textToVoice("이메일을 받는사람에 "+key+" 로 저장하고, 이메일 제목 단계로 이동 합니다.")
#                 email_recipients = key
#                 for_break = False
#                 break
#             else:
#                 print("이메일을 받는사람이 잘못 지정되었습니다. 다시 입력합니다.")
#                 textToVoice("이메일을 받는사람이 잘못 지정되었습니다. 다시 입력합니다.")
#                 input_email_recipients()

# ######################## 1.이메일 수신자 받기 끝 ########################




# ######################## 2.이메일 제목 받기 시작 ########################

# email_title = False #이메일 수신자가 처음엔 지징되어 있지않음
# for_break = True 

# while True:

#     if email_title: #이메일 제목이 지징되어 있으면 루프를 빠져나옴
#         break

#     if for_break == False: # 이중 루프를 빠져나가기 위한 변수 설정임
#         break

#     # print("이메일 시스템을 종료하려면 '굿바이'라고 말씀해 주세요.")
#     # textToVoice("이메일 시스템을 종료하려면 '굿바이'라고 말씀해 주세요.")

#     print("이메일 제목을 알려주세요.")
#     textToVoice("이메일 제목을 알려주세요.")
#     my_res = voiceToText()

#     if '굿바이' in my_res:
#         print("음성 이메일 시스템을 종료합니다.")
#         textToVoice("음성 이메일 시스템을 종료합니다.")
#         break

#     # for key in  emaildic.keys():
#     #     if '굿바이' in my_res:
#     #         print("음성 이메일 시스템을 종료합니다.2")
#     #         textToVoice("음성 이메일 시스템을 종료합니다.2")
#     #         for_break = False
#     #         break

#     #     print(key,"++++++++++++++++++++++++++++++++++++++")
#     # if key in my_res:
#     # if "홍길동" in my_res:
#     # 제목: 음성으로 이메일 보내기
#     print("이메일 제목이 "+my_res+" 이 맞습니까? 맞으면 yes, 아니면 no로 대답해 주세요.")
#     textToVoice("이메일 제목이 "+my_res+" 이 맞습니까? 맞으면 yes, 아니면 no로 대답해 주세요.")
#     my_res2 = voiceToText()

#     if my_res2 == "yes" or my_res2 == "예스":
#         print("이메일 제목을 "+my_res+" 로 저장하고, 이메일 본문 작성 단계로 이동 합니다.")
#         textToVoice("이메일 제목을 "+my_res+" 로 저장하고, 이메일 본문 작성 단계로 이동 합니다.")
#         email_title = my_res
#         break
#     else:
#         print("이메일 제목이 잘못 지정되었습니다. 다시 입력합니다.")
#         textToVoice("이메일 제목이 잘못 지정되었습니다. 다시 입력합니다.")
#         input_email_title()

# ######################## 2.이메일 제목 받기 끝 ########################





######################## 3.이메일 본문 받기 시작 ########################

email_contents = False #이메일 본문이 처음엔 지징되어 있지않음
for_break = True 

while True:

    if email_contents: #이메일 본문이 지징되어 있으면 루프를 빠져나옴
        break

    if for_break == False: # 이중 루프를 빠져나가기 위한 변수 설정임
        break

    print("이메일 본문 내용은 한 줄씩 입력합니다. 본문내용을 알려주세요.")
    textToVoice("이메일 본문 내용은 한 줄씩 입력합니다. 본문내용을 알려주세요.")
    my_res = voiceToText()+"\n\n"

    if '굿바이' in my_res:
        print("음성 이메일 시스템을 종료합니다.")
        textToVoice("음성 이메일 시스템을 종료합니다.")
        break

    # 본문: 음성으로 이메일 보내기입니다.
    # 몸이 불편하거나 연세가 많으신 분들을 위한 시스템입니다.
    print("조금전 말씀하신 이메일 본문내용이 "+my_res+" 가 맞습니까? 맞으면 yes, 아니면 no로 대답해 주세요.")
    textToVoice("조금전 말씀하신 이메일 본문내용이 "+my_res+" 가 맞습니까? 맞으면 yes, 아니면 no로 대답해 주세요.")
    my_res2 = voiceToText()

    if my_res2 == "yes" or my_res2 == "예스":
        print("조금전 말씀하신 이메일 본문내용을 저장하였습니다.")
        textToVoice("조금전 말씀하신 이메일 본문내용을 저장하였습니다.")
        email_contents = re.sub("False","",str(email_contents))
        email_contents = email_contents + my_res
        # break

        print("추가 입력 하겠습니까? 추가 입력하려면 yes, 아니면 no로 대답해 주세요.")
        textToVoice("추가 입력 하겠습니까? 추가 입력하려면 yes, 아니면 no로 대답해 주세요.")
        my_res3 = voiceToText()
        
        if my_res3 == "yes" or my_res3 == "예스":
            input_email_contents()
        else:

            print("전체 본문내용은 다음과 같습니다.\n\n")
            textToVoice("전체 본문내용은 다음과 같습니다.")
            print(email_contents)
            textToVoice(email_contents)

            print("본문내용 입력을 종료합니다.")
            textToVoice("본문내용 입력을 종료합니다.")
            for_break = False
            break


    else:
        print("이메일 본문내용이 잘못 입력되었습니다. 다시 입력 하겠습니다.")
        textToVoice("이메일 본문내용이 잘못 입력되었습니다. 다시 입력 하겠습니다.")
        input_email_contents()

######################## 3.이메일 본문 받기 끝 ########################

 

 - 소스파일을 cmd, 파워쉘 또는 vscode 등에서 아래와 같이 실행하시기 바랍니다.

 

 

 

 > python 4.py
 

 

 

 

 


 

O 주요 내용

 

-아래 소스코드에 대해서 간략히 설명합니다.

(대부분의 내용은 이전 글과 동일하며 다른 주요 부분만 설명합니다.)

 

 

 

 

 

1.메일 본문을 입력받는 함수 입니다.

본문 내용을 잘못 말한 경우 다시 받을 수 있도록 함수 형태로 만들어 두었습니다.

 

본문 내용은 제목과는 다르게 여러 줄이 입력될 수 있습니다.

따라서 여기서는 한줄씩 입력/확인을 반복하며, 추가 입력 여부를 확인 후 라인을 추가 하고 있습니다.

 

본문 내용은 추가 입력이 될 수 있으므로 아래와 같이 이전 본문 내용을 누적으로 받을 수 있도록 설정 해주었습니다.

email_contents = str(email_contents) + my_res (line 145)

 

 

 

추가 입력이 없는 경우(line 154)에는 전체 본문내용을 알려주고, 종료하게 됩니다.

 

 

 

 

처음 본문내용은 지정되어 있지 않으므로 아래와 같이 변수 설정을 해주었는데,

email_contents = False

 

추가입력이 있는 경우 email_contents 변수에 사용자가 추가한 내용을 계속 누적해 주어야 하는데, 보기 좋지 않게 본문 내용 맨 앞에 'False'가 추가됩니다.

 

따라서 이를 제거하기 위하여 아래와 같이 정규표현식을 사용하여 제거한 후 email_contents 변수에 추가된 본문내용을 누적시켜 주었습니다.

email_contents = re.sub("False","",str(email_contents)) (line 320)
email_contents = email_contents + my_res (line 321)

 

 

 

본문 내용 입력 후 추가입력 여부를 물어보고, 'yes'라도 답한 경우 다시 본문내용 입력 함수(input_email_contents())를 호출하도록 하고 있습니다. (line 328 ~ 330)

 

 

 

 

 

 


 

ㅁ 정리

 

O 우리가 배운 내용

 
 - 오늘은 음성으로 메일을 보내기 위해 세번째로 본문을 작성하는 방법에 대하여 살펴보았습니다.

 

 

 - 오늘 우리가 배운 내용을 간략히 정리해 보면 아래와 같습니다.

1. 이메일 본문 내용을 계속 입력할 수 있도록 아래와 같이 설정합니다.

>email_contents = email_contents + my_res

 

 

 

 

 

오늘은 여기까지이며, 댓글하트는 제가 이글을 지속할 수 있게 해주는 힘이 됩니다.

위의 내용이 유익하셨다면, 댓글과 하트 부탁드립니다.

 

 

 

 

감사합니다.

 

 

 

 

728x90
반응형
LIST