手把手教你使用Python打造一款摸魚倒計(jì)界面

前言

前段時(shí)間在微博看到一段摸魚人的倒計(jì)時(shí)模板,感覺還挺有趣的。


于是我用了一小時(shí)的時(shí)間寫了個(gè)頁面出來 摸魚辦地址 (當(dāng)然是摸魚的時(shí)間啦)。

模板是這樣的:

摸魚辦公室 ??

【摸魚辦公室】今天是 2021-11-30 星期二\

你好,摸魚人,工作再累,一定不要忘記摸魚哦 ! 有事沒事起身去茶水間去廊道去天臺走走,別老在工位上坐著。多喝點(diǎn)水,錢是老板的,但命是自己的 !

?? 距離 周末 放假還有 2 天

?? 距離 元旦 放假還有 3 天

?? 距離 過年 放假還有 34 天

?? 距離 清明節(jié) 放假還有 97 天

?? 距離 勞動節(jié) 放假還有 123 天

?? 距離 端午節(jié) 放假還有 156 天

?? 距離 中秋節(jié) 放假還有 255 天

?? 距離 國慶節(jié) 放假還有 276 天

由于前端是單頁面服務(wù),直接擼一個(gè)原始的html網(wǎng)頁就行。

FastAPI對于異步請求是一把好手、更輕、性能更佳。

掛上一層Nginx讓它看起來像那么回事兒。

實(shí)現(xiàn)過程

首先要知道、除了靜態(tài)文字之外的比如當(dāng)前日期、距離節(jié)日放假的天數(shù)等都是動態(tài)返回的,我需要使用 Jinja2 模板進(jìn)行動態(tài)綁定。

我應(yīng)該把重點(diǎn)放在時(shí)間的處理上。

而且在這個(gè)模板中,有陽歷的節(jié)日,也是陰歷的節(jié)日,我需要轉(zhuǎn)換。

初始化一個(gè) FastAPI 對象并聲明靜態(tài)頁面的模板目錄 (Jinja2Templates)

#?-*-?coding:?utf-8?-*-

import?datetime

from?fastapi?import?FastAPI,?Request

from?fastapi.responses?import?HTMLResponse

from?fastapi.templating?import?Jinja2Templates

from?zhdate?import?ZhDate?as?lunar_date

app?=?FastAPI(

????debug=False,

????title="My?API",

????docs_url="/docs",

????openapi_url=f"/openapi.json"

)

templates?=?Jinja2Templates(directory="templates")

可以看到的是我用到了zhdate這個(gè)庫、主要用于陰歷和陽歷之間的相互轉(zhuǎn)換。用法如下

today?=?datetime.date.today()

print(today.year,?today.month,?today.day)

print("大年時(shí)間:?",?lunar_date(today.year+1,?1,?1).to_datetime().date())

print("端午時(shí)間:?",?lunar_date(today.year,?5,?5).to_datetime().date())

print("中秋時(shí)間:?",?lunar_date(today.year,?8,?15).to_datetime().date())

print("元旦時(shí)間:?",?f"{today.year+1}-01-01")

print("清明時(shí)間:?",?f"{today.year}-04-05")

print("勞動時(shí)間:?",?f"{today.year}-05-01")

print("國慶時(shí)間:?",?f"{today.year}-10-01")

我們可以梳理一下:

計(jì)算距離大年、元旦的天數(shù)時(shí),要在年份上+1

計(jì)算距離其他節(jié)日的天數(shù)時(shí),要判斷天數(shù)差是否小于0,如果是,則年份需要+1,因?yàn)橐呀?jīng)過去的節(jié)日對此沒有意義

distance_big_year?=?(lunar_date(today.year?+?1,?1,?1).to_datetime().date()?-?today).days

distance_5_5?=?(lunar_date(today.year,?5,?5).to_datetime().date()?-?today).days

distance_5_5?=?distance_5_5?if?distance_5_5?>?0?else?(

????????lunar_date(today.year?+?1,?5,?5).to_datetime().date()?-?today).days

distance_8_15?=?(lunar_date(today.year,?8,?15).to_datetime().date()?-?today).days

distance_8_15?=?distance_8_15?if?distance_8_15?>?0?else?(

????????lunar_date(today.year?+?1,?8,?15).to_datetime().date()?-?today).days

distance_year?=?(datetime.datetime.strptime(f"{today.year?+?1}-01-01",?"%Y-%m-%d").date()?-?today).days

distance_4_5?=?(datetime.datetime.strptime(f"{today.year}-04-05",?"%Y-%m-%d").date()?-?today).days

distance_4_5?=?distance_4_5?if?distance_4_5?>?0?else?(

????????datetime.datetime.strptime(f"{today.year?+?1}-04-05",?"%Y-%m-%d").date()?-?today).days

distance_5_1?=?(datetime.datetime.strptime(f"{today.year}-05-01",?"%Y-%m-%d").date()?-?today).days

distance_5_1?=?distance_5_1?if?distance_5_1?>?0?else?(

????????datetime.datetime.strptime(f"{today.year?+?1}-05-01",?"%Y-%m-%d").date()?-?today).days

distance_10_1?=?(datetime.datetime.strptime(f"{today.year}-10-01",?"%Y-%m-%d").date()?-?today).days

distance_10_1?=?distance_10_1?if?distance_10_1?>?0?else?(

????????datetime.datetime.strptime(f"{today.year?+?1}-10-01",?"%Y-%m-%d").date()?-?today).days

怎么樣? 我的命名足夠瘋狂吧。 接下來需要計(jì)算一下距離周末的天數(shù)。

def?get_week_day(date):

????week_day_dict?=?{

????????0:?'星期一',

????????1:?'星期二',

????????2:?'星期三',

????????3:?'星期四',

????????4:?'星期五',

????????5:?'星期六',

????????6:?'星期天',

????}

????day?=?date.weekday()

????return?week_day_dict[day]

week_day_?=?get_week_day(today)

print(f"今天是:?{week_day_}")?#?先獲取今天是星期幾

按照每周5個(gè)工作日計(jì)算,今天距離周末的天數(shù)就是

5?-?today.weekday()?#?today.weekday()?今天距離周末

現(xiàn)在將所有的數(shù)據(jù)組裝起來

time_?=?[

????{"v_":?distance_year,?"title":?"元旦"},??#?距離元旦

????{"v_":?distance_big_year,?"title":?"過年"},??#?距離過年

????{"v_":?distance_4_5,?"title":?"清明節(jié)"},??#?距離清明

????{"v_":?distance_5_1,?"title":?"勞動節(jié)"},??#?距離勞動

????{"v_":?distance_5_5,?"title":?"端午節(jié)"},??#?距離端午

????{"v_":?distance_8_15,?"title":?"中秋節(jié)"},??#?距離中秋

????{"v_":?distance_10_1,?"title":?"國慶節(jié)"},??#?距離國慶

]

至于為什么是List而不是Dict,那是我需要做一個(gè)根據(jù)距離天數(shù)的排序,讓最先放假的節(jié)日放于最前面, 這樣看起來會舒服得多。

time_?=?sorted(time_,?key=lambda?x:?x['v_'],?reverse=False)

接下來要寫一個(gè) 路由,將數(shù)據(jù)傳入到html頁面中去。

@app.get("/",?response_class=HTMLResponse)

async?def?readme(request:?Request):

????return?templates.TemplateResponse("readme.html",

??????????????????????????????????????{"request":?request,?"time_":?time_,?"now_":?now_,?"week_day_":?week_day_})

來看一下完整的代碼 (main.py):

#?-*-?coding:?utf-8?-*-

import?datetime

from?fastapi?import?FastAPI,?Request

from?fastapi.responses?import?HTMLResponse

from?fastapi.templating?import?Jinja2Templates

from?zhdate?import?ZhDate?as?lunar_date

app?=?FastAPI(

????debug=False,

????title="My?API",

????docs_url=f"/docs",

????openapi_url=f"/openapi.json"

)

templates?=?Jinja2Templates(directory="templates")

today?=?datetime.date.today()

#?print(today.year,?today.month,?today.day)

#?print("大年時(shí)間:?",?lunar_date(today.year+1,?1,?1).to_datetime().date())

#?print("端午時(shí)間:?",?lunar_date(today.year,?5,?5).to_datetime().date())

#?print("中秋時(shí)間:?",?lunar_date(today.year,?8,?15).to_datetime().date())

#?print("元旦時(shí)間:?",?f"{today.year+1}-01-01")

#?print("清明時(shí)間:?",?f"{today.year+1}-04-05")

#?print("勞動時(shí)間:?",?f"{today.year+1}-05-01")

#?print("國慶時(shí)間:?",?f"{today.year+1}-10-01")

distance_big_year?=?(lunar_date(today.year?+?1,?1,?1).to_datetime().date()?-?today).days

distance_5_5?=?(lunar_date(today.year,?5,?5).to_datetime().date()?-?today).days

distance_5_5?=?distance_5_5?if?distance_5_5?>?0?else?(

????????lunar_date(today.year?+?1,?5,?5).to_datetime().date()?-?today).days

distance_8_15?=?(lunar_date(today.year,?8,?15).to_datetime().date()?-?today).days

distance_8_15?=?distance_8_15?if?distance_8_15?>?0?else?(

????????lunar_date(today.year?+?1,?8,?15).to_datetime().date()?-?today).days

distance_year?=?(datetime.datetime.strptime(f"{today.year?+?1}-01-01",?"%Y-%m-%d").date()?-?today).days

distance_4_5?=?(datetime.datetime.strptime(f"{today.year}-04-05",?"%Y-%m-%d").date()?-?today).days

distance_4_5?=?distance_4_5?if?distance_4_5?>?0?else?(

????????datetime.datetime.strptime(f"{today.year?+?1}-04-05",?"%Y-%m-%d").date()?-?today).days

distance_5_1?=?(datetime.datetime.strptime(f"{today.year}-05-01",?"%Y-%m-%d").date()?-?today).days

distance_5_1?=?distance_5_1?if?distance_5_1?>?0?else?(

????????datetime.datetime.strptime(f"{today.year?+?1}-05-01",?"%Y-%m-%d").date()?-?today).days

distance_10_1?=?(datetime.datetime.strptime(f"{today.year}-10-01",?"%Y-%m-%d").date()?-?today).days

distance_10_1?=?distance_10_1?if?distance_10_1?>?0?else?(

????????datetime.datetime.strptime(f"{today.year?+?1}-10-01",?"%Y-%m-%d").date()?-?today).days

def?get_week_day(date):

????week_day_dict?=?{

????????0:?'星期一',

????????1:?'星期二',

????????2:?'星期三',

????????3:?'星期四',

????????4:?'星期五',

????????5:?'星期六',

????????6:?'星期天',

????}

????day?=?date.weekday()

????return?week_day_dict[day]

#?print("距離大年:?",?distance_big_year)

#?print("距離端午:?",?distance_5_5)

#?print("距離中秋:?",?distance_8_15)

#?print("距離元旦:?",?distance_year)

#?print("距離清明:?",?distance_4_5)

#?print("距離勞動:?",?distance_5_1)

#?print("距離國慶:?",?distance_10_1)

#?print("距離周末:?",?5?-?today.weekday())

now_?=?f"{today.year}年{today.month}月{today.day}日"

week_day_?=?get_week_day(today)

time_?=?[

????{"v_":?5?-?1?-?today.weekday(),?"title":?"周末"},??#?距離周末

????{"v_":?distance_year,?"title":?"元旦"},??#?距離元旦

????{"v_":?distance_big_year,?"title":?"過年"},??#?距離過年

????{"v_":?distance_4_5,?"title":?"清明節(jié)"},??#?距離清明

????{"v_":?distance_5_1,?"title":?"勞動節(jié)"},??#?距離勞動

????{"v_":?distance_5_5,?"title":?"端午節(jié)"},??#?距離端午

????{"v_":?distance_8_15,?"title":?"中秋節(jié)"},??#?距離中秋

????{"v_":?distance_10_1,?"title":?"國慶節(jié)"},??#?距離國慶

]

time_?=?sorted(time_,?key=lambda?x:?x['v_'],?reverse=False)

@app.get("/",?response_class=HTMLResponse)

async?def?readme(request:?Request):

????return?templates.TemplateResponse("readme.html",

??????????????????????????????????????{"request":?request,?"time_":?time_,?"now_":?now_,?"week_day_":?week_day_})

if?__name__?==?'__main__':

????import?uvicorn

????uvicorn.run(app='main:app',?host="0.0.0.0",?port=8080,?reload=True)

最后就到了html頁面部分了,來看一下主要的傳值。

<center>

????【摸魚辦公室】今天是?{{?now_?}}?{{?week_day_?}}

????<br><br>

????{%?for?v_?in?time_?%}

????????<p>???距離?{{?v_.title?}}?放假還有?{{?v_.v_?}}?天</p>

????{%?else?%}

????????<p>沒有任何值</p>

????{%?endfor?%}

</center>

這樣整個(gè)的路由構(gòu)造和頁面編寫就算是完成了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容