重构,添加注释

This commit is contained in:
ZaneYork 2024-09-10 15:29:02 +08:00
parent 9ba075559c
commit c6f7658c0f
4 changed files with 111 additions and 40 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
/.idea/ /.idea/
*.sqlite3 *.sqlite3
/__pycache__/

59
dao.py
View File

@ -1,14 +1,15 @@
import sqlite3 import sqlite3
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import Generator
from flask import request from flask import request
db_path = './data.sqlite3' db_path = './data.sqlite3'
db = sqlite3.connect(db_path) ddl_db = sqlite3.connect(db_path)
cursor = db.cursor() ddl_cursor = ddl_db.cursor()
try: try:
cursor.execute(''' ddl_cursor.execute('''
create table if not exists user_menu create table if not exists user_menu
( (
user text, user text,
@ -17,32 +18,40 @@ create table if not exists user_menu
primary key (user, datestr) primary key (user, datestr)
) )
''') ''')
cursor.execute(''' ddl_cursor.execute('''
create table if not exists roll_result create table if not exists roll_result
( (
datestr text primary key, datestr text primary key,
value text value text
) )
''') ''')
cursor.execute(''' ddl_cursor.execute('''
create table if not exists menu create table if not exists menu
( (
name text primary key, name text primary key,
label text label text
) )
''') ''')
db.commit() ddl_db.commit()
finally: finally:
cursor.close() ddl_cursor.close()
db.close() ddl_db.close()
def get_user(): def get_user() -> str:
"""
根据访问IP决定用户ID
:return: 用户ID
"""
client_ip = request.remote_addr client_ip = request.remote_addr
return client_ip return client_ip
def get_user_menu(): def get_user_menu() -> str:
"""
获取当前用户的投票内容
:return: 投票内容
"""
user = get_user() user = get_user()
db = sqlite3.connect(db_path) db = sqlite3.connect(db_path)
cursor = db.cursor() cursor = db.cursor()
@ -63,7 +72,12 @@ def get_user_menu():
db.close() db.close()
def set_user_menu(menu, user=None): def set_user_menu(menu: str, user: str = None) -> None:
"""
设置用户投票内容
:param menu: 投票内容
:param user: 用户默认当前用户
"""
datestr = datetime.now().strftime('%Y-%m-%d') datestr = datetime.now().strftime('%Y-%m-%d')
if user is None: if user is None:
user = get_user() user = get_user()
@ -78,7 +92,10 @@ def set_user_menu(menu, user=None):
db.close() db.close()
def fetch_all_today_menu(): def fetch_all_user_today_menu() -> Generator[tuple[str, str], None, None]:
"""
获取所有用户今日的投票内容
"""
datestr = datetime.now().strftime('%Y-%m-%d') datestr = datetime.now().strftime('%Y-%m-%d')
db = sqlite3.connect(db_path) db = sqlite3.connect(db_path)
cursor = db.cursor() cursor = db.cursor()
@ -94,7 +111,10 @@ def fetch_all_today_menu():
db.close() db.close()
def fetch_all_menu(): def fetch_all_menu() -> Generator[tuple[str, str], None, None]:
"""
获取所有可点的菜单
"""
db = sqlite3.connect(db_path) db = sqlite3.connect(db_path)
cursor = db.cursor() cursor = db.cursor()
try: try:
@ -108,7 +128,12 @@ def fetch_all_menu():
db.close() db.close()
def fetch_roll_result(interval=0): def fetch_roll_result(interval: int = 0) -> str | None:
"""
获取N天前的抽签结果
:param interval: 间隔
:return: 抽签结果
"""
date = datetime.now() + timedelta(days=interval) date = datetime.now() + timedelta(days=interval)
datestr = date.strftime('%Y-%m-%d') datestr = date.strftime('%Y-%m-%d')
db = sqlite3.connect(db_path) db = sqlite3.connect(db_path)
@ -125,7 +150,11 @@ def fetch_roll_result(interval=0):
db.close() db.close()
def set_roll_result(value): def set_roll_result(value: str) -> None:
"""
写入抽签结果
:param value: 抽签结果
"""
datestr = datetime.now().strftime('%Y-%m-%d') datestr = datetime.now().strftime('%Y-%m-%d')
db = sqlite3.connect(db_path) db = sqlite3.connect(db_path)
cursor = db.cursor() cursor = db.cursor()

View File

@ -1,23 +1,35 @@
import json import json
from re import Pattern
from session import app from session import app
from flask import send_from_directory, render_template, request, make_response, abort from flask import render_template, make_response, abort
import re import re
import random import random
from dao import * from dao import *
MOBILE_AGENTS_PATTERN = re.compile( MOBILE_AGENTS_PATTERN: Pattern[str] = re.compile(
r"(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino", r"(android|bb\d+|meego).+mobile|avantgo|bada/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|"
r"ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)/|plucker|"
r"pocket|psp|series([46])0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino",
re.IGNORECASE, re.IGNORECASE,
) )
def is_mobile_request(user_agent): def is_mobile_request(user_agent: str) -> bool:
"""
判断是否是移动端
:param user_agent: UA
:return: 是否
"""
return bool(MOBILE_AGENTS_PATTERN.search(user_agent)) return bool(MOBILE_AGENTS_PATTERN.search(user_agent))
def fetch_menu_summary(): def fetch_user_menu_summary() -> dict[str, float]:
all_menu = list(fetch_all_today_menu()) """
获取今天所有人的投票汇总
:return: 品类->数量
"""
all_menu = list(fetch_all_user_today_menu())
if len(all_menu) > 0: if len(all_menu) > 0:
menus = list(map(lambda x: json.loads(x[1]), all_menu)) menus = list(map(lambda x: json.loads(x[1]), all_menu))
menu_keys = set() menu_keys = set()
@ -31,10 +43,14 @@ def fetch_menu_summary():
for k in x: for k in x:
result[k] += x[k] result[k] += x[k]
return result return result
return [] return {}
def within_time(): def within_time() -> bool:
"""
判断是否在投票时间内
:return: 是否
"""
start_time = datetime.strptime(str(datetime.now().date()) + ' 8:00', '%Y-%m-%d %H:%M') start_time = datetime.strptime(str(datetime.now().date()) + ' 8:00', '%Y-%m-%d %H:%M')
end_time = datetime.strptime(str(datetime.now().date()) + ' 17:30', '%Y-%m-%d %H:%M') end_time = datetime.strptime(str(datetime.now().date()) + ' 17:30', '%Y-%m-%d %H:%M')
if start_time < datetime.now() < end_time: if start_time < datetime.now() < end_time:
@ -42,15 +58,36 @@ def within_time():
return False return False
def check_roll(): def check_roll() -> int:
"""
判断是否能抽签
:return: 0 不可以, 1 可以, -1 已抽过
"""
result = fetch_roll_result() result = fetch_roll_result()
if result is not None: if result is not None:
return -1 return -1
return 0 if within_time() else 1 return 0 if within_time() else 1
def vote_reduce(summary: dict[str, float]) -> dict[str, float]:
"""
降低昨天点过的餐的中奖率
:param summary: 投票汇总结果
:return: 投票汇总结果
"""
last_result = fetch_roll_result(-1)
for k in summary:
if last_result == k:
summary[k] = summary[k] * 7 / 10
return summary
@app.route('/dinner/update') @app.route('/dinner/update')
def dinner_update(): def dinner_update():
"""
更新投票
:return: 响应内容
"""
user_agent_string = request.headers.get('User-Agent') user_agent_string = request.headers.get('User-Agent')
if not is_mobile_request(user_agent_string): if not is_mobile_request(user_agent_string):
abort(403) abort(403)
@ -75,17 +112,18 @@ def dinner_update():
@app.route('/dinner/roll') @app.route('/dinner/roll')
def dinner_roll(): def dinner_roll():
"""
发起抽签
:return: 响应
"""
if check_roll() != 1: if check_roll() != 1:
return make_response(json.dumps(dict(code=-1, data="目前不能抽签"))) return make_response(json.dumps(dict(code=-1, data="目前不能抽签")))
summary = fetch_menu_summary() summary = vote_reduce(fetch_user_menu_summary())
last_result = fetch_roll_result(-1)
for k in summary: for k in summary:
if last_result == k:
summary[k] = summary[k] * 7 / 10
summary[k] = int(round(summary[k] * 100)) summary[k] = int(round(summary[k] * 100))
pool = [] pool = []
for k in summary: for k in summary:
for i in range(summary[k]): for i in range(int(summary[k])):
pool.append(k) pool.append(k)
random.shuffle(pool) random.shuffle(pool)
result = pool[0] result = pool[0]
@ -95,16 +133,17 @@ def dinner_roll():
@app.route('/dinner') @app.route('/dinner')
def dinner(): def dinner():
"""
主页面
:return: 响应
"""
menu = get_user_menu() menu = get_user_menu()
if menu: if menu:
menu = json.loads(menu) menu = json.loads(menu)
else: else:
menu = {} menu = {}
summary = fetch_menu_summary() summary = vote_reduce(fetch_user_menu_summary())
last_result = fetch_roll_result(-1) last_result = fetch_roll_result(-1)
for x in summary:
if x == last_result:
summary[x] = summary[x] * 7 / 10
total_vote = sum(value for value in summary.values()) total_vote = sum(value for value in summary.values())
if total_vote == 0: if total_vote == 0:
total_vote = 1 total_vote = 1

View File

@ -1,20 +1,22 @@
import subprocess, os import os
from flask import render_template, redirect from flask import redirect, send_from_directory
import threading import threading
from dinner import * from dinner import *
from session import app from session import app
lock = threading.Lock() lock = threading.Lock()
@app.route('/') @app.route('/')
def index(): def index():
return redirect('dinner') return redirect('dinner')
# return render_template('index.html') # return render_template('index.html')
@app.route('/favicon.ico') @app.route('/favicon.ico')
def favicon(): def favicon():
return send_from_directory(os.path.join(app.root_path, 'static'), 'fd-logo.png') return send_from_directory(os.path.join(app.root_path, 'static'), 'fd-logo.png')
if __name__ == '__main__': if __name__ == '__main__':
app.run(host="0.0.0.0", port=80, debug=True, threaded=True) app.run(host="0.0.0.0", port=80, debug=True, threaded=True)