You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DjangoBlog/djangoblog/blog_signals.py

137 lines
4.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#gq:
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
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
logger = logging.getLogger(__name__)
# 自定义信号OAuth用户登录成功后触发
oauth_user_login_signal = django.dispatch.Signal(['id'])
# 自定义信号:需要发送邮件时触发
send_email_signal = django.dispatch.Signal(['emailto', 'title', 'content'])
@receiver(send_email_signal)
def send_email_signal_handler(sender, **kwargs):
"""发送HTML邮件并记录发送日志"""
emailto = kwargs['emailto']
title = kwargs['title']
content = kwargs['content']
msg = EmailMultiAlternatives(
title,
content,
from_email=settings.DEFAULT_FROM_EMAIL,
to=emailto)
msg.content_subtype = "html"
from servermanager.models import EmailSendLog
log = EmailSendLog()
log.title = title
log.content = content
log.emailto = ','.join(emailto)
try:
result = msg.send()
log.send_result = result > 0
except Exception as e:
logger.error(f"失败邮箱号: {emailto}, {e}")
log.send_result = False
log.save()
@receiver(oauth_user_login_signal)
def oauth_user_login_signal_handler(sender, **kwargs):
"""OAuth用户登录后处理头像本地化并清理侧边栏缓存"""
id = kwargs['id']
oauthuser = OAuthUser.objects.get(id=id)
site = get_current_site().domain
# 如果头像是外部链接,则下载本地化
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()
delete_sidebar_cache()
@receiver(post_save)
def model_post_save_callback(
sender,
instance,
created,
raw,
using,
update_fields,
**kwargs):
"""
模型保存后触发:
1. 对有get_full_url方法的模型如文章通知搜索引擎。
2. 对评论,清理相关缓存并异步发送邮件通知。
"""
clearcache = False
# 忽略Admin日志
if isinstance(instance, LogEntry):
return
# 处理内容模型(如文章)
if 'get_full_url' in dir(instance):
is_update_views = update_fields == {'views'}
# 非测试环境且非仅更新浏览量,则通知搜索引擎
if not settings.TESTING and not is_update_views:
try:
notify_url = instance.get_full_url()
SpiderNotify.baidu_notify([notify_url])
except Exception as ex:
logger.error("notify sipder", ex)
# 非仅更新浏览量,则标记需要清理缓存
if not is_update_views:
clearcache = True
# 处理评论
if isinstance(instance, Comment):
if instance.is_enable:
path = instance.article.get_absolute_url()
site = get_current_site().domain
if site.find(':') > 0:
site = site[0:site.find(':')]
# 清理文章页、评论、侧边栏等相关缓存
expire_view_cache(path, servername=site, serverport=80, key_prefix='blogdetail')
if cache.get('seo_processor'):
cache.delete('seo_processor')
comment_cache_key = 'article_comments_{id}'.format(id=instance.article.id)
cache.delete(comment_cache_key)
delete_sidebar_cache()
delete_view_cache('article_comments', [str(instance.article.pk)])
# 异步发送评论通知邮件
_thread.start_new_thread(send_comment_email, (instance,))
# 根据标记清理全局缓存
if clearcache:
cache.clear()
@receiver(user_logged_in)
@receiver(user_logged_out)
def user_auth_callback(sender, request, user, **kwargs):
"""用户登录/登出后,清理侧边栏缓存"""
if user and user.username:
logger.info(user)
delete_sidebar_cache()
# cache.clear() # 注释掉了全局缓存清理,仅清理侧边栏