Files
diary-family/core/tasks.py
xiaji 2921ab8dda feat(tasks): 添加调试任务用于测试Celery和Redis连接
refactor(test_redis_celery): 使用urllib解析Redis URL并改进错误处理
2026-01-17 21:35:34 +08:00

149 lines
4.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from celery import shared_task
from django.utils import timezone
from datetime import timedelta
from django.core.mail import EmailMessage
from django.conf import settings
from django.shortcuts import render
import os
from loguru import logger
# WeasyPrint可用性标记初始为None
WEASYPRINT_AVAILABLE = None
# 获取WeasyPrint可用性
def is_weasyprint_available():
"""检查WeasyPrint是否可用"""
global WEASYPRINT_AVAILABLE
if WEASYPRINT_AVAILABLE is None:
try:
from weasyprint import HTML
WEASYPRINT_AVAILABLE = True
except ImportError:
logger.warning("WeasyPrint库无法导入PDF功能将不可用")
WEASYPRINT_AVAILABLE = False
return WEASYPRINT_AVAILABLE
from .models import (
ReadingRecord,
InsightRecord,
FamilyTask,
TodayPlan,
SystemConfig
)
@shared_task
def generate_daily_pdf_report():
"""生成每日PDF报告"""
logger.info("开始执行每日PDF报告生成任务")
# 检查WeasyPrint是否可用
if not is_weasyprint_available():
logger.error("WeasyPrint库不可用无法生成PDF报告")
return False
today = timezone.now().date()
today_str = today.strftime('%Y-%m-%d')
# 生成报告数据
report_date = today
yesterday = report_date - timedelta(days=1)
# 获取昨日记录
yesterday_reading = ReadingRecord.objects.filter(date=yesterday)
yesterday_insight = InsightRecord.objects.filter(date=yesterday)
# 获取今日计划
today_plan = TodayPlan.objects.filter(date=report_date)
# 获取家庭事项统计
from django.db.models import Count
family_task_stats = FamilyTask.objects.values('type').annotate(count=Count('id'))
# 准备上下文
context = {
'today': report_date,
'yesterday': yesterday,
'yesterday_reading': yesterday_reading,
'yesterday_insight': yesterday_insight,
'today_plan': today_plan,
'family_task_stats': family_task_stats,
}
# 渲染HTML模板
html_string = render(None, 'core/report_pdf.html', context).content.decode('utf-8')
# 生成PDF报告
pdf_file = f"report_{today_str}.pdf"
pdf_path = os.path.join(settings.REPORTS_ROOT, pdf_file)
# 确保报告目录存在
os.makedirs(settings.REPORTS_ROOT, exist_ok=True)
# 生成PDF - 动态导入WeasyPrint
try:
from weasyprint import HTML
HTML(string=html_string).write_pdf(pdf_path)
logger.info(f"PDF报告生成成功: {pdf_path}")
return True
except Exception as e:
logger.error(f"PDF报告生成失败: {str(e)}")
return False
@shared_task
def send_daily_report():
"""发送每日报告"""
logger.info("开始执行每日报告发送任务")
# 先生成PDF报告
pdf_generated = generate_daily_pdf_report()
if not pdf_generated:
logger.error("PDF报告生成失败无法发送邮件")
return False
today = timezone.now().date()
today_str = today.strftime('%Y-%m-%d')
# 获取系统配置
config = SystemConfig.get_config()
# 检查邮件配置是否完整
if not all([config.smtp_server, config.smtp_username, config.smtp_password, config.recipient_email]):
logger.error("邮件配置不完整,无法发送邮件")
return False
# 发送邮件
subject = f"家庭日报 - {today_str}"
message = f"这是您的家庭日报,日期:{today_str}"
from_email = config.smtp_username
recipient_list = [config.recipient_email]
# PDF文件路径
pdf_file = f"report_{today_str}.pdf"
pdf_path = os.path.join(settings.REPORTS_ROOT, pdf_file)
try:
email = EmailMessage(
subject=subject,
body=message,
from_email=from_email,
to=recipient_list,
)
# 添加附件
with open(pdf_path, 'rb') as f:
email.attach(pdf_file, f.read(), 'application/pdf')
# 发送邮件
email.send()
logger.info(f"邮件发送成功,收件人:{config.recipient_email}")
return True
except Exception as e:
logger.error(f"邮件发送失败:{str(e)}")
return False
@shared_task
def debug_task():
"""调试任务用于测试Celery和Redis连接"""
from loguru import logger
logger.info("调试任务执行成功")
return {"status": "success", "message": "Celery任务执行正常", "timestamp": timezone.now().isoformat()}