flask實戰-我的博客-電子郵件支持

電子郵件支持

由於博客要支持評論,因此咱們須要在文章有了新評論後發郵件通知管理員。並且,當管理員回覆了讀者的評論後,也須要發送郵件提醒讀者。html

 

爲了方便讀者使用示例程序,personalBlog中仍然使用Flask-Mail來發送郵件。讀者在運行程序前須要在項目根目錄內建立.env文件寫入對應的環境變量,以便讓發信功能正常工做。flask

 

由於郵件的內容很簡單,咱們將直接在發信函數中寫出正文內容,這裏只提供了HTML正文。咱們有兩個須要使用電子郵件的場景:app

 

一、當文章有新評論時,發送郵件給管理員;異步

二、當某個評論被回覆時,發送郵件給被回覆用戶。async

 

爲了方便使用,咱們在emails.py中分別爲這兩個使用場景建立了特定的發信函數,能夠直接在視圖函數中調用 。這些函數內部則經過咱們建立的通用發信函數send_email()來發送郵件,以下所示 :ide

 

personalBlog/emails.py: 提醒郵件函數函數

 

from flask import url_for

def send_mail(subject, to, html):
    pass

def send_new_comment_email(post):
# blog.show_post是blog藍本下的show_post視圖函數
    post_url = url_for('blog.show_post', post_id = post.id, _external = True) + '#comments'
    send_mail(subject = 'New comment', to = current_app.config['BLUEBLOG_ADMIN_EMAIL'],
              html = '<p>New comment in post <i>%s</i>, click the link below to check:</p>'
                     '<p><a href="%s">%s</a></p>'
                     '<p><small style = "color:#868e96">Do not reply this email.</small></p>'
                     % (post.title, post_url, post_url))

def send_new_reply_email(comment):
    post_url = url_for('blog.show_post', post_id = comment.post_id, _external = True) + '#comments'
    send_mail(subject = 'New reply', to = comment.email,
              html = '<p>New reply for the comment you left in post <i>%s</i>, click the link below to check: </p>'
                     '<p><a href="%s">%s</a></p>'
                     '<p><small style="color: #868e96">Do not reply this email.</small></p>'
                     % (comment.post.title, post_url, post_url))
 

send_new_comment_email()函數用來發送新評論提醒郵件。 咱們經過將url_for()函數的_external參數設爲True來構建外部連接。連接尾部的#comments是用來跳轉到頁面評論部分的URL片斷(URL fragment),comments是評論部分div元素的id值。這個函數接收表示文章的post對象做爲參數,從而生成文章正文的標題和連接。post

 

URL片斷又稱片斷標識符(fragment identifier),是URL中用來表示頁面中資源位置的短字符,以#開頭,對於HTML頁面來講,一個典型的示例是文章頁面的評論區。假設評論區的div元素id爲comment,若是咱們訪問http://example.com/post/7#comment,頁面加載完成後將會直接跳到評論部分。this

 

send_new_reply_email()函數則用來發送新回覆提醒郵件。這個發信函數接收comment對象做爲參數,用來構建郵件正文,所屬文章的主鍵值經過comment.post_id屬性獲取,標題則經過comment.post.titlle屬性獲取。url

 

在personalBlog源碼中,咱們沒有使用異步的方式發送郵件,若是你但願編寫一個異步發送郵件的通用發信函數send_mail(),和以前介紹的基本相同,以下所示

 

from threading import Thread
from flask import current_app
from flask_mail import Message

from personalBlog.extensions import mail

def _send_async_mail(app, message):
    with app.app_context():
        mail.send(message)

def send_async_mail(subjecct, to, html):
    app = current_app._get_current_object() # 獲取被代理的真實對象
    message = Message(subjecct, recipients=[to], html = html)
    thr = Thread(target = _send_async_mail, args = [app, message])
    thr.start()
    return thr

 

須要注意,由於咱們的程序是經過工廠函數建立的,因此實例化Thread類時,咱們使用代理對象current_app做爲args參數列表中app的值。另外,由於在新建線程時須要真正的程序對象來建立上下文,因此不能直接傳入current_app,而是傳入current_app調用_get_current_app()方法獲取的被代理的程序實例。

相關文章
相關標籤/搜索