2020-09-01 kk日记,flask+flask-apscheduler的应用

1、前言

最近都在“玩”flask,其中玩的出发点就是即使是实验项目都应该有价值所在,所以在上一篇实现无广告看小说后,这次要进一步丰富系统的功能——后台作业定时检测小说是否更新,如果更新了就自动下载。

2、设计

  1. 有一个作业配置文件——jobconifg.py
  2. 有一个作业前端,可以指定固定间隔执行程序,也可一删除作业。——shedule.html

前端布局比较low,大家不要计较。

    3. flask主程序负责调用作业。

3、代码

3.1 jobconfig.py

该文件主要由两部分组成:

  1. 作业运行程序的主体代码,是一个函数/方法,如jobcheckdmzupdate
  2. 函数字典,用于描述函数的元数据,并用于schedule.html 加载函数列表 和 flask-apscheduler 运行函数。

在下面示例代码里主要有两个功能,一检查爽文小说是否有更新,二、发邮件。

# -*- coding: utf-8 -*-
defaultencoding = 'utf-8'
import random
import time
import requests
import json
import datetime
import pickle
import threading
import schedule
from bs4 import BeautifulSoup
import urllib2
import sys
import pandas
from GetNovels import damengzhu
import logging
from flask_mail  import Mail,Message
from flask import Flask

reload(sys)
sys.setdefaultencoding(defaultencoding)
app=Flask("__name__")
app.config['MAIL_SERVER'] = 'mail.ixxx.com'
app.config['MAIL_PORT'] = 25
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USE_SSL'] = False
app.config['MAIL_USERNAME'] = 'kk@ixxx.com'
app.config['MAIL_PASSWORD'] = 'password'
mail=Mail(app)
# 每添加一个函数都需要在这里添加到jobConfig里
jobConfig=[{
  "job_id":"job-check-dmz-update",
  "job_name":"jobcheckdmzupdate",
  "job_args":""
},
{
  "job_id":"job-testa",
  "job_name":"jobtesta",
  "job_args":(mail,app)
}
]

def jobcheckdmzupdate():

    dmz=damengzhu.DaMengZhu("./novel/","http://www.xbiquge.la/15/15977")
    result=dmz.checkUpdate()
    print result
    return result

def jobtesta(mail,app):
    # sender 发送方,recipients 接收方列表
    with app.app_context():
        msg = Message("This is a test ", sender='mars.he@infinitus-int.com',
                         recipients=['mars.he@infinitus-int.com'])
        # 邮件内容
        msg.body = "Flask test mail"
        # 发送邮件
        mail.send(msg)
        print "Mail sent"
        return "Sent Succeed"

3.2 schdule.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{topic}}</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.1.0/css/bootstrap.min.css">
    <script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://cdn.staticfile.org/popper.js/1.12.5/umd/popper.min.js"></script>
    <script src="https://cdn.staticfile.org/twitter-bootstrap/4.1.0/js/bootstrap.min.js"></script>

</head>
<body>
<script>

  function show_all_job(){
  $.post('/showalljob',function(data){
<!--  alert("abc")-->
  $('#job_list').html(data)
  jobs = JSON.parse(data)
  var div_show_all_job=document.getElementById("f_show_all_job")
  var table_show_all_job=document.createElement("table");
  table_show_all_job.setAttribute("class","table table-hover")
  for(var j=0;j<jobs.length;j++){
<!--    document.write(jobs[j].job_id)-->
    var v_tr=document.createElement("tr");
    var v_td1=document.createElement("td");
    var v_td2=document.createElement("td");
    var v_cb1=document.createElement("input");
    v_cb1.setAttribute("type","checkbox");
    v_cb1.setAttribute("name","removejob");
    v_cb1.setAttribute("value",jobs[j].job_id);
    var v_tn1=document.createTextNode(jobs[j].job_id)
    var v_tn2=document.createTextNode(jobs[j].job_anme)
<!--    v_cb1.appendChild(v_tn1)-->
    v_td1.appendChild(v_cb1)
    v_td1.appendChild(v_tn1)
    v_td2.appendChild(v_tn2)
    v_tr.appendChild(v_td1)
    v_tr.appendChild(v_td2)
    table_show_all_job.appendChild(v_tr)
    }
    div_show_all_job.appendChild(table_show_all_job)
<!--    var div_remove_job=document.getElementById("div_remove_job")-->
    $("#div_remove_job").hide()
  }
  )
  }


</script>
{% include 'header.html' %}


<div style="background:LightGreen;width:500px;float:left" align="center">
<form role="form" action='/schedule/submit' method="post">

 <div>
  <label> 添加作业 </label>
<!--  <input type="text" maxlength="30" name="taskDesc" value="task 1">-->
 </div>

 <div >
<label>调用函数:</label>
<select name="funcname">
    {% for j in jobs %}
    <option value={{j}}>{{j}}</option>
    {%endfor%}
</select>


 </div>


 <div>
    <label >
        <input type="radio" name="optionsRadio" id="optionsMin" value="everymin" checked> 每<input type="text" name="everymin" id="everymin_at" value="1"  maxlength="10">分钟执行1次
    </label>
</div>

 <div>
    <label >
        <input type="radio" name="optionsRadio" id="optionsHour" value="everyhour" > 每<input type="text" name="everyhour" id="everyhour_at" value="1" maxlength="10">小时执行1次
    </label>
</div>

 <div>
    <label >
        <input type="radio" name="optionsRadio" id="optionsDay" value="everyDay" > 每天<input type="text" name="everyDay" id="everyDay_at" value="10:00" maxlength="10">执行1次
    </label>
</div>

                            <button  class="btn btn-success"  type="submit" value="确定"> 确定 </button>

</form>

</div>

<div id="div_show_all_job" style="background-color:lightblue;float:left;width:700px" aling="left">
<button id="show_all_job" style="" align="left"  class="btn btn-success" value="显示所有作业" onclick="show_all_job()"> 显示所有作业</button>

<!--    <pre id="job_list"> </pre>-->
    <form id="f_show_all_job" action="/schedule/removejob" method="post">
       <input class="btn btn-success" type="submit" name="deljob" value="删除">
    </form>
</div>

这里总结一下,在实验过程中,顺带也学习了一些js的知识,实现数据和渲染。常用的函数:

var v1=document.getElementById("tagID名字") 获取当前页面的布局的根标签,然后创建字节点标签,并把数据和标签绑定。

var v_p1=document.createElement("p")

var v_p1_text=document.createTextNode("string")

现在上面的三个对象是没有关系,需要使用appendChild函数把它们建立期树状关系:

v_p1.appendChild(v_p1_text)

v1.appendChild(v_p1)

这样就可以把p 标签和数据动态添加到html上。

动态数据获取重要函数$.post(url,parameter,function(data){})具体用法查看“https://www.runoob.com/jquery/jquery-ajax-get-post.html

使用了这个函数后,就可以动态调用接口获取数据,并且进行数据和标签的绑定。示例如下:

function show_all_job(){
  $.post('/showalljob',function(data){
<!--  alert("abc")-->
  $('#job_list').html(data)
  jobs = JSON.parse(data)
  var div_show_all_job=document.getElementById("f_show_all_job")
  var table_show_all_job=document.createElement("table");
  table_show_all_job.setAttribute("class","table table-hover")
  for(var j=0;j<jobs.length;j++){
<!--    document.write(jobs[j].job_id)-->
    var v_tr=document.createElement("tr");
    var v_td1=document.createElement("td");
    var v_td2=document.createElement("td");
    var v_cb1=document.createElement("input");
    v_cb1.setAttribute("type","checkbox");
    v_cb1.setAttribute("name","removejob");
    v_cb1.setAttribute("value",jobs[j].job_id);
    var v_tn1=document.createTextNode(jobs[j].job_id)
    var v_tn2=document.createTextNode(jobs[j].job_anme)
<!--    v_cb1.appendChild(v_tn1)-->
    v_td1.appendChild(v_cb1)
    v_td1.appendChild(v_tn1)
    v_td2.appendChild(v_tn2)
    v_tr.appendChild(v_td1)
    v_tr.appendChild(v_td2)
    table_show_all_job.appendChild(v_tr)
    }
    div_show_all_job.appendChild(table_show_all_job)
<!--    var div_remove_job=document.getElementById("div_remove_job")-->
    $("#div_remove_job").hide()
  }
  )
  }

 

3.3 主程序

功能描述

1. 导入jobconfig 包,让flask-apscheduler可以运行指定函数。

2. 设置路由指向前端schedule.html页面

3. 添加addjob  \removejob \showjobs 的功能函数。

import  flask_apscheduler.scheduler as Scheduler
from Jobs import jobconfig as jc

scheduler = flask_apscheduler.APScheduler()
@app.route('/schedule',methods=['POST','GET'])
def ShowSchedule():
    jobs=[]
    for j in jc.jobConfig:
        jobs.append(j["job_name"])
    # jc.jobtesta(mail)
    joblist=scheduler.get_jobs()
    return render_template('schedule.html',jobs=jobs,joblist=joblist)

@app.route('/schedule/submit',methods=['POST','GET'])
def ShowScheduleSubmit():
    funcname="jc."+request.form["funcname"]
    funcargs=[]
    for jd in jc.jobConfig:
        if request.form["funcname"]==jd["job_name"]:
            funcargs=jd["job_args"]
            # if "mail" in jd["job_args"]:
            #     funcargs.append(mail)
            #     funcargs.append(app)
    print funcname
    job = {
            'id':funcname,  # 任务的唯一ID,不要冲突
            'func':funcname,   # 执行任务的function名称
            'args': funcargs # 如果function需要参数,就在这里添加
        }
    optionsRadio=request.form["optionsRadio"]
    # # print request.form["everyhour"]
    # # print request.form["taskDesc"]
    # job["func"]='mailtest'
    # job["args"]=()
    if optionsRadio=='everyhour':
        taskinterval=int(request.form["everyhour"])
        print taskinterval
        scheduler.add_job(func=__name__ + ':' + job['func'], id=job['id'],args=job["args"],trigger='interval', hours=taskinterval)
        # schedule.every(taskinterval).hours.do(test)
    elif optionsRadio=='everymin':
        taskinterval = int(request.form["everymin"])
        print type(taskinterval)
        scheduler.add_job(func=__name__ + ':' + job['func'], id=job['id'],args=job["args"],trigger='interval', minutes=taskinterval)
        # schedule.every(taskinterval).minutes.do(test)

    # return str(scheduler.get_jobs())
    for j in scheduler.get_jobs():
        print j.name
    return "成功"
@app.route("/schedule/removejob",methods=["post","get"])
def RemoveJob():
    # form.getlist获取同名的所有表单内容,并存为list
    jobids=request.form.getlist("removejob")
    print jobids
    # jobid = request.form["removejob"]
    for jobid in jobids:
        scheduler.remove_job(jobid)
    return "删除成功"

@app.route("/showalljob",methods=["post",'get'])
def ShowAllJob():
    joblist=[]
    for j in scheduler.get_jobs():
        joblist.append({"job_id":j.id,"job_anme":j.name})
        # joblist.append(j)
    # joblist=scheduler.get_jobs()
    joblist=json.dumps(joblist)
    return joblist


if __name__=='__main__':
    app.config.from_object(Config())

    # it is also possible to enable the API directly
    # scheduler.api_enabled = True
    logging.basicConfig()
    scheduler.init_app(app) #这个相当于插件与flask绑定的关系。
    scheduler.start()

    app.run(debug=True)

4、总结

边学,边实践,边记录。

期望有一天能够作出一个真正能为自己服务,增长财富的工具。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值