基于Python繪制一個摸魚倒計(jì)時(shí)界面
前言
前段時(shí)間在微博看到一段摸魚人的倒計(jì)時(shí)模板,感覺還挺有趣的。

于是我用了一小時(shí)的時(shí)間寫了個頁面出來 摸魚辦地址 (當(dāng)然是摸魚的時(shí)間啦)。
模板是這樣的:
摸魚辦公室 ??
【摸魚辦公室】今天是 2021-11-30 星期二
你好,摸魚人,工作再累,一定不要忘記摸魚哦 ! 有事沒事起身去茶水間去廊道去天臺走走,別老在工位上坐著。多喝點(diǎn)水,錢是老板的,但命是自己的 !
?? 距離 周末 放假還有 2 天
?? 距離 元旦 放假還有 3 天
?? 距離 過年 放假還有 34 天
?? 距離 清明節(jié) 放假還有 97 天
?? 距離 勞動節(jié) 放假還有 123 天
?? 距離 端午節(jié) 放假還有 156 天
?? 距離 中秋節(jié) 放假還有 255 天
?? 距離 國慶節(jié) 放假還有 276 天
- 由于前端是單頁面服務(wù),直接擼一個原始的 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í)間的處理上。
而且在這個模板中,有陽歷的節(jié)日,也是陰歷的節(jié)日,我需要轉(zhuǎn)換。
初始化一個 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 這個庫、主要用于陰歷和陽歷之間的相互轉(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 個工作日計(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,那是我需要做一個根據(jù)距離天數(shù)的排序,讓最先放假的節(jié)日放于最前面, 這樣看起來會舒服得多。
time_ = sorted(time_, key=lambda x: x['v_'], reverse=False)
接下來要寫一個 路由,將數(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òu)造和頁面編寫就算是完成了。
最后通過 Nginx 部署到我的站點(diǎn)上。
摸魚辦預(yù)覽地址

代碼已經(jīng)上傳:https://github.com/PY-GZKY/moyu?
到此這篇關(guān)于基于Python繪制一個摸魚倒計(jì)時(shí)界面的文章就介紹到這了,更多相關(guān)Python倒計(jì)時(shí)界面內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
pyinstaller打包單個exe后無法執(zhí)行錯誤的解決方法
今天小編就為大家分享一篇pyinstaller打包單個exe后無法執(zhí)行錯誤的解決方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-06-06
pytorch實(shí)現(xiàn)MNIST手寫體識別
這篇文章主要為大家詳細(xì)介紹了pytorch實(shí)現(xiàn)MNIST手寫體識別,使用全連接神經(jīng)網(wǎng)絡(luò),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02
基于python批量處理dat文件及科學(xué)計(jì)算方法詳解
今天小編就為大家分享一篇基于python批量處理dat文件及科學(xué)計(jì)算方法詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05
關(guān)于django 數(shù)據(jù)庫遷移(migrate)應(yīng)該知道的一些事
今天小編就為大家分享一篇關(guān)于django 數(shù)據(jù)庫遷移(migrate)應(yīng)該知道的一些事,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05
python + winrm 實(shí)現(xiàn)遠(yuǎn)程連接Windows服務(wù)器并執(zhí)行指定命令的操作過程
Windows遠(yuǎn)程管理(WinRM)是Windows Server 2003 R2,Windows Vista和Windows Server 2008中一種新式的方便遠(yuǎn)程管理的服務(wù),這篇文章主要介紹了python + winrm 實(shí)現(xiàn)遠(yuǎn)程連接Windows服務(wù)器并執(zhí)行指定命令的操作過程,需要的朋友可以參考下2023-10-10
python 從csv讀數(shù)據(jù)到mysql的實(shí)例
今天小編就為大家分享一篇python 從csv讀數(shù)據(jù)到mysql的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-06-06
Python操作Sqlite正確實(shí)現(xiàn)方法解析
我們今天將會在這篇文章中分步驟為大家詳細(xì)介紹一下有關(guān)Python操作Sqlite的相關(guān)應(yīng)用方式,希望大家可以從中獲得一些幫助2020-02-02

