253 lines
9.6 KiB
Python
253 lines
9.6 KiB
Python
|
|
"""
|
||
|
|
이메일 발송을 위한 유틸리티 함수들
|
||
|
|
"""
|
||
|
|
from django.core.mail import send_mail
|
||
|
|
from django.conf import settings
|
||
|
|
from django.template.loader import render_to_string
|
||
|
|
from django.utils import timezone
|
||
|
|
import json
|
||
|
|
import threading
|
||
|
|
from datetime import datetime
|
||
|
|
|
||
|
|
|
||
|
|
def send_withdrawal_notification(withdrawal_request):
|
||
|
|
"""
|
||
|
|
회원탈퇴 승인 시 관리자에게 탈퇴 정보를 이메일로 발송
|
||
|
|
|
||
|
|
Args:
|
||
|
|
withdrawal_request: WithdrawalRequest 객체
|
||
|
|
"""
|
||
|
|
try:
|
||
|
|
person = withdrawal_request.person
|
||
|
|
user = withdrawal_request.user
|
||
|
|
backup_data = withdrawal_request.backup_data
|
||
|
|
|
||
|
|
# 이메일 제목
|
||
|
|
subject = f"[신라 AMP] 회원탈퇴 처리 완료 - {person.이름}"
|
||
|
|
|
||
|
|
# 이메일 내용 구성
|
||
|
|
approved_date_str = withdrawal_request.approved_date.strftime('%Y년 %m월 %d일 %H시 %M분') if withdrawal_request.approved_date else '처리 중'
|
||
|
|
email_content = f"""
|
||
|
|
=== 신라 AMP 회원탈퇴 처리 완료 ===
|
||
|
|
|
||
|
|
탈퇴 처리 일시: {approved_date_str}
|
||
|
|
승인자: {withdrawal_request.approved_by.username if withdrawal_request.approved_by else '시스템'}
|
||
|
|
|
||
|
|
=== 탈퇴한 회원 정보 ===
|
||
|
|
이름: {person.이름}
|
||
|
|
전화번호: {user.username}
|
||
|
|
탈퇴 요청일: {withdrawal_request.request_date.strftime('%Y년 %m월 %d일 %H시 %M분')}
|
||
|
|
탈퇴 사유: {withdrawal_request.reason or '사유 없음'}
|
||
|
|
|
||
|
|
=== 탈퇴 전 수정된 정보 ===
|
||
|
|
"""
|
||
|
|
|
||
|
|
# 백업 데이터가 있으면 추가
|
||
|
|
if backup_data and 'person_info' in backup_data:
|
||
|
|
person_info = backup_data['person_info']
|
||
|
|
email_content += f"검색 키워드: {person_info.get('keyword1', '없음')}\n"
|
||
|
|
email_content += f"소개글: {person_info.get('소개글', '없음')}\n"
|
||
|
|
email_content += f"가입일시: {person_info.get('가입일시', '없음')}\n"
|
||
|
|
email_content += f"전화번호: {person_info.get('연락처', '없음')}\n"
|
||
|
|
email_content += f"소속: {person_info.get('소속', '없음')}\n"
|
||
|
|
email_content += f"직책: {person_info.get('직책', '없음')}\n"
|
||
|
|
|
||
|
|
email_content += f"""
|
||
|
|
=== 원본 정보로 복원 ===
|
||
|
|
- Person 정보가 peopleinfo.py의 원본 데이터로 복원되었습니다.
|
||
|
|
- User 계정이 삭제되었습니다.
|
||
|
|
- Person과 User 연결이 해제되었습니다.
|
||
|
|
|
||
|
|
=== 관리자 메모 ===
|
||
|
|
{withdrawal_request.admin_notes or '없음'}
|
||
|
|
|
||
|
|
---
|
||
|
|
신라 AMP 시스템에서 자동 발송된 메일입니다.
|
||
|
|
"""
|
||
|
|
|
||
|
|
# 이메일 발송
|
||
|
|
send_mail(
|
||
|
|
subject=subject,
|
||
|
|
message=email_content,
|
||
|
|
from_email=settings.DEFAULT_FROM_EMAIL,
|
||
|
|
recipient_list=['cpabong.com@gmail.com'],
|
||
|
|
fail_silently=False,
|
||
|
|
)
|
||
|
|
|
||
|
|
print(f"[EMAIL] 탈퇴 알림 이메일 발송 성공: {person.이름}")
|
||
|
|
return True
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
print(f"[EMAIL_ERROR] 탈퇴 알림 이메일 발송 실패: {e}")
|
||
|
|
return False
|
||
|
|
|
||
|
|
|
||
|
|
def test_email_settings():
|
||
|
|
"""이메일 설정 테스트"""
|
||
|
|
try:
|
||
|
|
send_mail(
|
||
|
|
subject='[신라 AMP] 이메일 설정 테스트',
|
||
|
|
message='이메일 설정이 정상적으로 작동합니다.',
|
||
|
|
from_email=settings.DEFAULT_FROM_EMAIL,
|
||
|
|
recipient_list=['cpabong.com@gmail.com'],
|
||
|
|
fail_silently=False,
|
||
|
|
)
|
||
|
|
print("[EMAIL] 테스트 이메일 발송 성공")
|
||
|
|
return True
|
||
|
|
except Exception as e:
|
||
|
|
print(f"[EMAIL_ERROR] 테스트 이메일 발송 실패: {e}")
|
||
|
|
return False
|
||
|
|
|
||
|
|
|
||
|
|
def send_withdrawal_request_notification(user, person, reason):
|
||
|
|
"""
|
||
|
|
회원탈퇴 요청 시 관리자에게 탈퇴 정보를 이메일로 발송 (백그라운드)
|
||
|
|
|
||
|
|
Args:
|
||
|
|
user: User 객체
|
||
|
|
person: Person 객체
|
||
|
|
reason: 탈퇴 사유
|
||
|
|
"""
|
||
|
|
def _send_email():
|
||
|
|
try:
|
||
|
|
# 이메일 제목
|
||
|
|
subject = f"[신라 AMP] 회원탈퇴 요청 - {person.이름}"
|
||
|
|
|
||
|
|
# 현재 회원 정보 수집
|
||
|
|
current_info = {
|
||
|
|
'user_info': {
|
||
|
|
'username': user.username,
|
||
|
|
'email': user.email,
|
||
|
|
'date_joined': user.date_joined.isoformat() if user.date_joined else None,
|
||
|
|
'last_login': user.last_login.isoformat() if user.last_login else None,
|
||
|
|
},
|
||
|
|
'person_info': {
|
||
|
|
'이름': person.이름,
|
||
|
|
'소속': person.소속,
|
||
|
|
'생년월일': person.생년월일.isoformat() if person.생년월일 else None,
|
||
|
|
'직책': person.직책,
|
||
|
|
'연락처': person.연락처,
|
||
|
|
'주소': person.주소,
|
||
|
|
'사진': person.사진.name if person.사진 else None,
|
||
|
|
'TITLE': person.TITLE,
|
||
|
|
'SEQUENCE': person.SEQUENCE,
|
||
|
|
'keyword1': person.keyword1,
|
||
|
|
'소개글': person.소개글,
|
||
|
|
'모든사람보기권한': person.모든사람보기권한,
|
||
|
|
'비밀번호설정필요': person.비밀번호설정필요,
|
||
|
|
'가입일시': person.가입일시.isoformat() if person.가입일시 else None,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# 이메일 내용 구성
|
||
|
|
email_content = f"""
|
||
|
|
=== 신라 AMP 회원탈퇴 요청 ===
|
||
|
|
|
||
|
|
탈퇴 요청 일시: {timezone.now().strftime('%Y년 %m월 %d일 %H시 %M분')}
|
||
|
|
|
||
|
|
=== 탈퇴 요청자 정보 ===
|
||
|
|
이름: {person.이름}
|
||
|
|
전화번호: {user.username}
|
||
|
|
탈퇴 사유: {reason or '사유 없음'}
|
||
|
|
|
||
|
|
=== 현재 회원정보 ===
|
||
|
|
"""
|
||
|
|
|
||
|
|
# 현재 정보 추가
|
||
|
|
if current_info and 'person_info' in current_info:
|
||
|
|
person_info = current_info['person_info']
|
||
|
|
email_content += f"검색 키워드: {person_info.get('keyword1', '없음')}\n"
|
||
|
|
email_content += f"소개글: {person_info.get('소개글', '없음')}\n"
|
||
|
|
email_content += f"가입일시: {person_info.get('가입일시', '없음')}\n"
|
||
|
|
email_content += f"전화번호: {person_info.get('연락처', '없음')}\n"
|
||
|
|
email_content += f"소속: {person_info.get('소속', '없음')}\n"
|
||
|
|
email_content += f"직책: {person_info.get('직책', '없음')}\n"
|
||
|
|
|
||
|
|
email_content += f"""
|
||
|
|
|
||
|
|
=== 처리 안내 ===
|
||
|
|
- Django Admin에서 탈퇴 요청을 승인 또는 거부할 수 있습니다.
|
||
|
|
- 승인 시 위 정보가 백업되고 계정이 삭제됩니다.
|
||
|
|
- 거부 시 해당 회원에게 SMS로 알림이 전송됩니다.
|
||
|
|
|
||
|
|
---
|
||
|
|
신라 AMP 시스템에서 자동 발송된 메일입니다.
|
||
|
|
"""
|
||
|
|
|
||
|
|
# 이메일 발송
|
||
|
|
send_mail(
|
||
|
|
subject=subject,
|
||
|
|
message=email_content,
|
||
|
|
from_email=settings.DEFAULT_FROM_EMAIL,
|
||
|
|
recipient_list=['cpabong.com@gmail.com'],
|
||
|
|
fail_silently=False,
|
||
|
|
)
|
||
|
|
|
||
|
|
print(f"[EMAIL] 탈퇴 요청 이메일 발송 성공: {person.이름}")
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
print(f"[EMAIL_ERROR] 탈퇴 요청 이메일 발송 실패: {e}")
|
||
|
|
|
||
|
|
# 백그라운드 스레드에서 이메일 발송
|
||
|
|
email_thread = threading.Thread(target=_send_email)
|
||
|
|
email_thread.daemon = True
|
||
|
|
email_thread.start()
|
||
|
|
print(f"[EMAIL] 탈퇴 요청 이메일 백그라운드 발송 시작: {person.이름}")
|
||
|
|
|
||
|
|
|
||
|
|
def test_withdrawal_email():
|
||
|
|
"""탈퇴 이메일 템플릿 테스트"""
|
||
|
|
try:
|
||
|
|
# 가상의 백업 데이터로 테스트
|
||
|
|
test_backup_data = {
|
||
|
|
'user_info': {
|
||
|
|
'username': '01033433319',
|
||
|
|
'email': '',
|
||
|
|
'date_joined': '2025-08-23T16:24:35',
|
||
|
|
'last_login': '2025-08-23T16:27:44'
|
||
|
|
},
|
||
|
|
'person_info': {
|
||
|
|
'이름': '김봉수',
|
||
|
|
'소속': '신라대학교',
|
||
|
|
'생년월일': '1979-03-19',
|
||
|
|
'직책': '교수',
|
||
|
|
'연락처': '01033433319',
|
||
|
|
'주소': '부산시 사상구',
|
||
|
|
'사진': 'profile_photos/김봉수.png',
|
||
|
|
'TITLE': 'AMP 8기',
|
||
|
|
'SEQUENCE': 1,
|
||
|
|
'keyword1': '테스트키워드',
|
||
|
|
'소개글': '테스트 소개글입니다',
|
||
|
|
'모든사람보기권한': True,
|
||
|
|
'비밀번호설정필요': False,
|
||
|
|
'가입일시': '2025-08-23T16:24:35'
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# 테스트용 가상 WithdrawalRequest 객체
|
||
|
|
class TestWithdrawalRequest:
|
||
|
|
def __init__(self):
|
||
|
|
self.person = type('Person', (), {'이름': '김봉수'})()
|
||
|
|
self.user = type('User', (), {'username': '01033433319'})()
|
||
|
|
self.backup_data = test_backup_data
|
||
|
|
self.request_date = timezone.now()
|
||
|
|
self.reason = '테스트 탈퇴 사유'
|
||
|
|
self.approved_date = timezone.now()
|
||
|
|
self.approved_by = type('User', (), {'username': 'admin'})()
|
||
|
|
self.admin_notes = '테스트 관리자 메모'
|
||
|
|
|
||
|
|
# 테스트 이메일 발송
|
||
|
|
test_request = TestWithdrawalRequest()
|
||
|
|
result = send_withdrawal_notification(test_request)
|
||
|
|
|
||
|
|
if result:
|
||
|
|
print("[EMAIL] 탈퇴 이메일 테스트 발송 성공")
|
||
|
|
else:
|
||
|
|
print("[EMAIL] 탈퇴 이메일 테스트 발송 실패")
|
||
|
|
|
||
|
|
return result
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
print(f"[EMAIL_ERROR] 탈퇴 이메일 테스트 실패: {e}")
|
||
|
|
return False
|