diff --git a/src/DjangoBlog/blog_signals.py b/src/DjangoBlog/blog_signals.py new file mode 100644 index 0000000..95fcab0 --- /dev/null +++ b/src/DjangoBlog/blog_signals.py @@ -0,0 +1,163 @@ +#yyb 导入必要的Python和Django模块 +import _thread +import logging + +import django.dispatch +from django.conf import settings +from django.contrib.admin.models import LogEntry +from django.contrib.auth.signals import user_logged_in, user_logged_out +from django.core.mail import EmailMultiAlternatives +from django.db.models.signals import post_save +from django.dispatch import receiver + +#yyb 导入自定义模型和工具函数 +from comments.models import Comment +from comments.utils import send_comment_email +from djangoblog.spider_notify import SpiderNotify +from djangoblog.utils import cache, expire_view_cache, delete_sidebar_cache, delete_view_cache +from djangoblog.utils import get_current_site +from oauth.models import OAuthUser + +#yyb 获取logger实例 +logger = logging.getLogger(__name__) + +#yyb 定义自定义信号 +#yyb OAuth用户登录信号,传递用户id +oauth_user_login_signal = django.dispatch.Signal(['id']) +#yyb 发送邮件信号,传递收件人、标题和内容 +send_email_signal = django.dispatch.Signal( + ['emailto', 'title', 'content']) + + +@receiver(send_email_signal) +def send_email_signal_handler(sender, **kwargs): + """#yyb 发送邮件信号处理器""" + #yyb 从信号参数中获取邮件相关信息 + emailto = kwargs['emailto'] + title = kwargs['title'] + content = kwargs['content'] + + #yyb 创建邮件消息对象 + msg = EmailMultiAlternatives( + title, + content, + from_email=settings.DEFAULT_FROM_EMAIL, + to=emailto) + msg.content_subtype = "html" #yyb 设置邮件内容类型为HTML + + #yyb 记录邮件发送日志 + from servermanager.models import EmailSendLog + log = EmailSendLog() + log.title = title + log.content = content + log.emailto = ','.join(emailto) + + try: + #yyb 尝试发送邮件 + result = msg.send() + log.send_result = result > 0 #yyb 发送成功结果为True + except Exception as e: + #yyb 记录发送失败日志 + logger.error(f"失败邮箱号: {emailto}, {e}") + log.send_result = False + log.save() #yyb 保存邮件发送日志 + + +@receiver(oauth_user_login_signal) +def oauth_user_login_signal_handler(sender, **kwargs): + """#yyb OAuth用户登录信号处理器""" + id = kwargs['id'] + oauthuser = OAuthUser.objects.get(id=id) + site = get_current_site().domain + + #yyb 如果用户头像不在当前站点域名下,则保存头像到本地 + if oauthuser.picture and not oauthuser.picture.find(site) >= 0: + from djangoblog.utils import save_user_avatar + oauthuser.picture = save_user_avatar(oauthuser.picture) + oauthuser.save() + + #yyb 删除侧边栏缓存 + delete_sidebar_cache() + + +@receiver(post_save) +def model_post_save_callback( + sender, + instance, + created, + raw, + using, + update_fields, + **kwargs): + """#yyb 模型保存后的通用回调函数""" + clearcache = False + + #yyb 如果是LogEntry(Django管理员日志),直接返回 + if isinstance(instance, LogEntry): + return + + #yyb 检查实例是否有get_full_url方法(通常是有URL的模型) + if 'get_full_url' in dir(instance): + #yyb 判断是否只是更新浏览量 + is_update_views = update_fields == {'views'} + + #yyb 如果不是测试环境且不是更新浏览量,则通知搜索引擎 + if not settings.TESTING and not is_update_views: + try: + notify_url = instance.get_full_url() + SpiderNotify.baidu_notify([notify_url]) #yyb 通知百度搜索引擎 + except Exception as ex: + logger.error("notify sipder", ex) + + #yyb 如果不是更新浏览量,设置清除缓存标志 + if not is_update_views: + clearcache = True + + #yyb 如果是评论模型 + if isinstance(instance, Comment): + #yyb 如果评论是启用的 + if instance.is_enable: + path = instance.article.get_absolute_url() + site = get_current_site().domain + + #yyb 处理站点域名(移除端口号) + if site.find(':') > 0: + site = site[0:site.find(':')] + + #yyb 使文章详情页缓存过期 + expire_view_cache( + path, + servername=site, + serverport=80, + key_prefix='blogdetail') + + #yyb 删除SEO处理器缓存 + if cache.get('seo_processor'): + cache.delete('seo_processor') + + #yyb 删除文章评论缓存 + comment_cache_key = 'article_comments_{id}'.format( + id=instance.article.id) + cache.delete(comment_cache_key) + + #yyb 删除侧边栏缓存 + delete_sidebar_cache() + #yyb 删除文章评论视图缓存 + delete_view_cache('article_comments', [str(instance.article.pk)]) + + #yyb 在新线程中发送评论通知邮件 + _thread.start_new_thread(send_comment_email, (instance,)) + + #yyb 如果需要清除缓存 + if clearcache: + cache.clear() #yyb 清除所有缓存 + + +@receiver(user_logged_in) +@receiver(user_logged_out) +def user_auth_callback(sender, request, user, **kwargs): + """#yyb 用户登录/登出信号处理器""" + if user and user.username: + logger.info(user) #yyb 记录用户信息 + delete_sidebar_cache() #yyb 删除侧边栏缓存 + # cache.clear() #yyb 注释掉的清除所有缓存代码 \ No newline at end of file