Teach you how to use Python to create a fishing countdown interface

Hello, I'm boss Wu.

preface

Some time ago, I saw a fishing man's countdown template on Weibo. I felt very interesting.

So I spent an hour writing a page to find the address of the Fishing Office (fishing time, of course).

The template is as follows:

Fishing Office 🐟

Hello, fisherman, no matter how tired you are, you must not forget to fish! If you have nothing to do, get up and go to the tea room, the corridor and the roof. Don't always sit on the station. Drink more water. The money belongs to the boss, but the life belongs to you!

🐟 Two days before the weekend holiday

🐟 There are three days before the new year's Day holiday

🐟 There are 34 days before the Chinese New Year holiday

🐟 There are 97 days before the Tomb Sweeping Day holiday

🐟 123 days before Labor Day holiday

🐟 There are 156 days before the Dragon Boat Festival holiday

🐟 There are 255 days before the Mid Autumn Festival holiday

🐟 There are 276 days before the National Day holiday

  • Since the front-end is a single page service, you can directly create an original html page.
  • FastAPI is a good hand for asynchronous requests, lighter and better performance.
  • Put up a layer of "Nginx" to make it look like that.

Implementation process

  • First of all, except for static text, such as the current date and the number of days from the holiday are returned dynamically. I need to use the Jinja2 template for dynamic binding.
  • I should focus on dealing with time.
  • And in this template, there are both Gregorian and lunar festivals. I need to convert them.

Initialize a FastAPI object and declare the template directory (Jinja2Templates) of the static page

*- 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")` 

As you can see, I used the "zhdate" library, which is mainly used for the conversion between the lunar calendar and the Gregorian calendar. The usage is as follows

today = datetime.date.today()
print(today.year, today.month, today.day)
print("New year time: ", lunar_date(today.year+1, 1, 1).to_datetime().date())
print("Dragon Boat Festival time: ", lunar_date(today.year, 5, 5).to_datetime().date())
print("Mid Autumn Festival time: ", lunar_date(today.year, 8, 15).to_datetime().date())
print("New year's day time: ", f"{today.year+1}-01-01")
print("Qingming time: ", f"{today.year}-04-05")
print("Working hours: ", f"{today.year}-05-01")
print("National day time: ", f"{today.year}-10-01")

We can sort out:

  • When calculating the number of days from , New Year's day and new year's day, + 1 should be added to the year
  • When calculating the number of days away from , other festivals , judge whether the number of days difference is less than , 0. If so, the year needs to be + 1, because the past festivals 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? My name is crazy enough.

Next, you need to calculate the number of days from the weekend.

def get_week_day(date):
    week_day_dict = {
        0: 'Monday',
        1: 'Tuesday',
        2: 'Wednesday',
        3: 'Thursday',
        4: 'Friday',
        5: 'Saturday',
        6: 'Sunday',
    }
    day = date.weekday()
    return week_day_dict[day]

week_day_ = get_week_day(today)
print(f"Today is: {week_day_}") #Get the day of the week first

Based on {5 working days per week, the number of days between today and the weekend is

5 - today.weekday() # today.weekday() today is the weekend

Now assemble all the data

time_ = [
    {"v_": distance_year, "title": "New year's Day"},  #Distance from New Year's Day
    {"v_": distance_big_year, "title": "celebrate the Spring Festival"},  #Distance from the Chinese New Year
    {"v_": distance_4_5, "title": "the Pure Brightness Festival"},  #Distance to Qingming
    {"v_": distance_5_1, "title": "labor day"},  #Distance labor
    {"v_": distance_5_5, "title": "The Dragon Boat Festival"},  #Distance to Dragon Boat Festival
    {"v_": distance_8_15, "title": "Mid-Autumn Festival"},  #Distance from Mid Autumn Festival
    {"v_": distance_10_1, "title": "National Day"},  #Distance from National Day
]

As for why it is "List" instead of "Dict", I need to make a ranking according to the number of days away, so that the festival with the first holiday is placed at the front, which will look much more comfortable.

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

Next, we need to write a route to transfer 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_})

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("big year time:", lunar_date(today.year+1, 1, 1) to_ datetime(). date())
#print("Dragon Boat Festival time:", lunar_date(today.year, 5, 5) to_ datetime(). date())
#print("Mid Autumn Festival time:", lunar_date(today.year, 8, 15) to_ datetime(). date())
#print("New Year's day time:", f"{today.year+1}-01-01")
#print("Qingming time:", f"{today.year+1}-04-05")
#print("labor time:", f"{today.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: 'Tuesday',
        2: 'Wednesday',
        3: 'Thursday',
        4: 'Friday',
        5: 'Saturday',
        6: 'Sunday',
    }
    day = date.weekday()
    return week_day_dict[day]

#print("distance_big_year:", distance_big_year)
#print("distance from Dragon Boat Festival:", distance_5_5)
#print("distance from Mid Autumn Festival:", distance_8_15)
#print("distance from New Year's Day:", distance_year)
#print("distance Qingming:", distance_4_5)
#print("distance labor:", distance_5_1)
#print("distance from National Day:", distance_10_1)
#print("distance from weekend:", 5 - today.weekday())

now_ = f"{today.year}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"},  #Distance from New Year's Day
    {"v_": distance_big_year, "title": "celebrate the Spring Festival"},  #Distance from the Chinese New Year
    {"v_": distance_4_5, "title": "the Pure Brightness Festival"},  #Distance to Qingming
    {"v_": distance_5_1, "title": "labor day"},  #Distance labor
    {"v_": distance_5_5, "title": "The Dragon Boat Festival"},  #Distance to Dragon Boat Festival
    {"v_": distance_8_15, "title": "Mid-Autumn Festival"},  #Distance from Mid Autumn Festival
    {"v_": distance_10_1, "title": "National Day"},  #Distance from National 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)

Finally, we'll come to the html page. Let's take a look at the main value transfer.

<center>
    [[Fishing Office] today is {{ now_ }} {{ week_day_ }}
    <br><br>
    {% for v_ in time_ %}
        <p>🐟 distance {{ v_.title }} Holidays and {{ v_.v_ }} day</p>
    {% else %}
        <p>No value</p>
    {% endfor %}

</center>

In this way, the whole route construction and page writing are completed.

Finally, it is deployed to my site through Nginx.

Preview address of Fishing Office

The code has been uploaded to} Fishing Office:

https://github.com/PY-GZKY/moyu

You may have more ideas, you can discuss them in the comment area, all for fishing.

Guys, practice it quickly! If you encounter any problems during the learning process, welcome to add my friends. I'll pull you into the Python learning exchange group to discuss learning together.

Keywords: Python Python crawler python3

Added by giannisptr on Mon, 03 Jan 2022 03:27:04 +0200