Hello, I’m Boss Wu.

preface

Some time ago, I saw a countdown template of people who touch fish on Weibo, which was quite interesting.

So I spent an hour writing a page to create the address of the fish office (the time of the fish, of course).

The template looks like this:

Fishing office

Today is Tuesday, 2021-11-30

Hello, fish person, work no matter how tired, must not forget to fish oh! Something is nothing to get up to go to the tea room to walk the corridor to the roof, do not sit on the station. Drink more water, money is the boss, but life is their own!

There are two days left before the weekend holiday

There are three days left before the New Year holiday

There are 34 days left before the Chinese New Year holiday

There are 97 days left before the Tomb-sweeping Day holiday

There are 123 days until the Labor Day holiday

There are 156 days left before the Dragon Boat Festival holiday

There are 255 days until the Chuseok holiday

There are 276 days left until the National Day holiday

  • Since the front end is a single page service, a raw HTML page can be directly stroked.
  • FastAPI is a great, lighter, and better performance tool for asynchronous requests.
  • Hang a layer of Nginx to make it look that way.

The implementation process

  • The first thing to know is that anything other than static text such as the current date, the number of days since the holiday, etc. is returned dynamically and I need to use the Jinja2 template for dynamic binding.
  • I should have focused on time management.
  • And in this template, there are holidays in the solar calendar, also in the lunar calendar, and I need to switch.

Initialize a FastAPI object and declare the static page’s template directory (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")
Copy the code

As you can see, I used the zhdate library, mainly for converting between lunar and solar calendars. Use the following

Date = datetime.date.today() print(today.year, today.month, today.day) print(" ", lunar_date(today.year+1, 1, 1).to_datetime().date()) print(" ", lunar_date(today.year, 5, 5).to_datetime().date()) print(" ", lunar_date (today. Year, 8, 15). To_datetime (). The date ()) print (" New Year's day time:, "f" {today. The year + 1} - 01-01 ") print (" qingming festival time: , "f" {today. Year} - 04 - '05 ") print (" labor time:, "f" {today. Year} - 05-01 ") print (", "National Day time, f" {today. Year} - 10-01 ")Copy the code

We can sort it out:

  • Calculate the number of days from the big year, New Year’s day, to the year on +1

  • When calculating the number of days away from other holidays, determine whether the difference is less than 0. If so, the year needs to be +1, since past holidays have no meaning for this

    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

How’s that? I think my naming is crazy enough.

Then you need to calculate the number of days until the weekend.

Def get_week_day (date) : week_day_dict = {0: 'on Monday, 1:' on Tuesday, 2: 'on Wednesday, 3:' on Thursday, 4: 'Friday, 5:' Saturday, 6: } day = date.weekday() return week_day_dict[day] week_day_ = get_week_day(today) print(f" {week_day_}") #Copy the code

Based on the 5 working days per week, today is the number of days to the weekend

5 - today.weekday() # today.weekday(Copy the code

Now assemble all the data

Time_ = [{" v_ ": distance_year," title ":" New Year's day "}, # from New Year's day {" v_ ": distance_big_year," title ":" New Year "}, New Year's day {# distance "v_" : Distance_4_5, "title" : "qingming festival"}, # distance tomb-sweeping {" v_ ": distance_5_1," title ":" labor day "}, {# from labor "v_" : distance_5_5, "title" : Dragon Boat Festival "Dragon Boat Festival"}, # distance {" v_ ": distance_8_15," title ":" Mid-Autumn festival "}, # distance Mid-Autumn {" v_ ": distance_10_1," title ":" National Day "}, National Day] # distanceCopy the code

As for why it was a List instead of Dict, I needed to do a sort by distance, and put the first holiday first so it would look much more comfortable.

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

The next step is to write a route that passes the data to the HTML page.

@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_})
Copy the code

Take a look at the complete code (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(" today.year, today.month, today.day" ", lunar_date(today.year+1, 1, 1).to_datetime().date()) # print(" ", lunar_date(today.year, 5, 5).to_datetime().date()) # print(" ", lunar_date (today. Year, 8, 15). To_datetime (). The date ()) # print (" New Year's day time:, "f" {today. The year + 1} - 01-01 ") # print (" qingming festival time: "F" {today. The year + 1} - 04 - '05) # print "(" labor time:," f "{today. The year + 1} - 05-01") # print (" National Day time: ", 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: 'Monday', 1: 'on Tuesday, 2:' on Wednesday, 3: 'on Thursday, 4:' Friday, 5: 'Saturday, 6: } day = date.weekday() return week_day_dict[day] # print(" distance_big_year: ", distance_big_year) # print(" distance_big_year: ") ", distance_year) # print(" distance_year: ", distance_year) # print(" distance_year: ") # print(" distance_year: ") # print(" ", distance_4_5) # print (" labor: distance, "distance_5_1) # print (" from the National Day:" distance_10_1) # print (" distance weekend: ", 5 - today.weekday()) now_ = f"{today.year} {today.month} month {today.day} day "week_day_ = get_week_day(today) time_ = [{"v_": 5-1 - today. Weekday (), "title" : "weekend"}, # distance weekend {" v_ ": distance_year," title ":" New Year's day "}, {# from New Year's day "v_" : Distance_big_year, "title" : "New Year"}, # distance for {" v_ ": distance_4_5," title ":" qingming festival "}, {# distance qingming festival "v_" : distance_5_1, "title" : "Labor day"}, # from labor {" v_ ": distance_5_5," title ":" the Dragon Boat Festival "}, # distance dragon boat {" v_ ": distance_8_15," title ":" Mid-Autumn festival "}, # distance Mid-Autumn {" v_ ": Distance_10_1, "title": "National Day "}, # remote day] 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)Copy the code

Finally, we come to the HTML page section, where we take a look at the main pass values.

< center > today is fishing in the office 】 【 {{now_}} {{week_day_}} < br > < br > {% for v_ in time_ %} < p > distance {{v_. Title}} and {{v_. V_}} the holiday Day < / p >} else {% % < p > no value < / p > {% endfor %} < / center >Copy the code

This completes the entire route construction and page authoring.

Finally deployed to my site via Nginx.

Touch fish do preview address

The code has been uploaded to the Fishing office:

https://github.com/PY-GZKY/moyu
Copy the code

You may have more ideas to discuss in the comments section, all for fishing.

Friends, quickly use the practice! If you have any problems during the learning process, please add me as a friend and I will invite you to join the Python Learning exchange group to discuss and learn together.