2024-09-10 10:55:19 +08:00
|
|
|
import json
|
2024-09-10 15:29:02 +08:00
|
|
|
from re import Pattern
|
2024-09-10 10:55:19 +08:00
|
|
|
|
|
|
|
from session import app
|
2024-09-10 15:29:02 +08:00
|
|
|
from flask import render_template, make_response, abort
|
2024-09-10 10:55:19 +08:00
|
|
|
import re
|
|
|
|
import random
|
|
|
|
from dao import *
|
|
|
|
|
2024-09-10 15:29:02 +08:00
|
|
|
MOBILE_AGENTS_PATTERN: Pattern[str] = re.compile(
|
|
|
|
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",
|
2024-09-10 10:55:19 +08:00
|
|
|
re.IGNORECASE,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2024-09-10 15:29:02 +08:00
|
|
|
def is_mobile_request(user_agent: str) -> bool:
|
|
|
|
"""
|
|
|
|
判断是否是移动端
|
|
|
|
:param user_agent: UA
|
|
|
|
:return: 是否
|
|
|
|
"""
|
2024-09-10 10:55:19 +08:00
|
|
|
return bool(MOBILE_AGENTS_PATTERN.search(user_agent))
|
|
|
|
|
|
|
|
|
2024-09-10 15:29:02 +08:00
|
|
|
def fetch_user_menu_summary() -> dict[str, float]:
|
|
|
|
"""
|
|
|
|
获取今天所有人的投票汇总
|
|
|
|
:return: 品类->数量
|
|
|
|
"""
|
|
|
|
all_menu = list(fetch_all_user_today_menu())
|
2024-09-10 10:55:19 +08:00
|
|
|
if len(all_menu) > 0:
|
|
|
|
menus = list(map(lambda x: json.loads(x[1]), all_menu))
|
|
|
|
menu_keys = set()
|
|
|
|
for x in menus:
|
|
|
|
for k in x:
|
|
|
|
menu_keys.add(k)
|
|
|
|
result = {}
|
|
|
|
for k in menu_keys:
|
|
|
|
result[k] = 0
|
|
|
|
for x in menus:
|
|
|
|
for k in x:
|
|
|
|
result[k] += x[k]
|
|
|
|
return result
|
2024-09-10 15:29:02 +08:00
|
|
|
return {}
|
2024-09-10 10:55:19 +08:00
|
|
|
|
|
|
|
|
2024-09-10 15:29:02 +08:00
|
|
|
def within_time() -> bool:
|
|
|
|
"""
|
|
|
|
判断是否在投票时间内
|
|
|
|
:return: 是否
|
|
|
|
"""
|
2024-09-10 10:55:19 +08:00
|
|
|
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')
|
|
|
|
if start_time < datetime.now() < end_time:
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
2024-09-10 15:29:02 +08:00
|
|
|
def check_roll() -> int:
|
|
|
|
"""
|
|
|
|
判断是否能抽签
|
|
|
|
:return: 0 不可以, 1 可以, -1 已抽过
|
|
|
|
"""
|
2024-09-10 10:55:19 +08:00
|
|
|
result = fetch_roll_result()
|
|
|
|
if result is not None:
|
|
|
|
return -1
|
|
|
|
return 0 if within_time() else 1
|
|
|
|
|
|
|
|
|
2024-09-10 15:29:02 +08:00
|
|
|
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
|
|
|
|
|
|
|
|
|
2024-09-10 10:55:19 +08:00
|
|
|
@app.route('/dinner/update')
|
|
|
|
def dinner_update():
|
2024-09-10 15:29:02 +08:00
|
|
|
"""
|
|
|
|
更新投票
|
|
|
|
:return: 响应内容
|
|
|
|
"""
|
2024-09-10 10:55:19 +08:00
|
|
|
user_agent_string = request.headers.get('User-Agent')
|
|
|
|
if not is_mobile_request(user_agent_string):
|
|
|
|
abort(403)
|
|
|
|
if check_roll() != 0:
|
|
|
|
return make_response(json.dumps(dict(code=-1, data="来晚了,提交失败")))
|
|
|
|
value = request.args.get('value').strip()
|
|
|
|
if not value:
|
|
|
|
set_user_menu('')
|
|
|
|
return make_response(json.dumps(dict(code=0, data="OK")))
|
|
|
|
value = json.loads(value)
|
|
|
|
summary = 0
|
|
|
|
for key in value:
|
|
|
|
summary += int(value[key])
|
|
|
|
if summary <= 0:
|
|
|
|
set_user_menu('')
|
|
|
|
return make_response(json.dumps(dict(code=0, data="OK")))
|
|
|
|
for key in value:
|
|
|
|
value[key] = int(value[key]) / summary
|
|
|
|
set_user_menu(json.dumps(value))
|
|
|
|
return make_response(json.dumps(dict(code=0, data="OK")))
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/dinner/roll')
|
|
|
|
def dinner_roll():
|
2024-09-10 15:29:02 +08:00
|
|
|
"""
|
|
|
|
发起抽签
|
|
|
|
:return: 响应
|
|
|
|
"""
|
2024-09-10 10:55:19 +08:00
|
|
|
if check_roll() != 1:
|
|
|
|
return make_response(json.dumps(dict(code=-1, data="目前不能抽签")))
|
2024-09-10 15:29:02 +08:00
|
|
|
summary = vote_reduce(fetch_user_menu_summary())
|
2024-09-10 10:55:19 +08:00
|
|
|
for k in summary:
|
|
|
|
summary[k] = int(round(summary[k] * 100))
|
|
|
|
pool = []
|
|
|
|
for k in summary:
|
2024-09-10 15:29:02 +08:00
|
|
|
for i in range(int(summary[k])):
|
2024-09-10 10:55:19 +08:00
|
|
|
pool.append(k)
|
|
|
|
random.shuffle(pool)
|
|
|
|
result = pool[0]
|
|
|
|
set_roll_result(result)
|
|
|
|
return make_response(json.dumps(dict(code=0, data="OK")))
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/dinner')
|
|
|
|
def dinner():
|
2024-09-10 15:29:02 +08:00
|
|
|
"""
|
|
|
|
主页面
|
|
|
|
:return: 响应
|
|
|
|
"""
|
2024-09-10 10:55:19 +08:00
|
|
|
menu = get_user_menu()
|
|
|
|
if menu:
|
|
|
|
menu = json.loads(menu)
|
|
|
|
else:
|
|
|
|
menu = {}
|
2024-09-10 15:29:02 +08:00
|
|
|
summary = vote_reduce(fetch_user_menu_summary())
|
2024-09-10 10:55:19 +08:00
|
|
|
last_result = fetch_roll_result(-1)
|
2024-09-10 11:31:03 +08:00
|
|
|
total_vote = sum(value for value in summary.values())
|
|
|
|
if total_vote == 0:
|
|
|
|
total_vote = 1
|
|
|
|
result = fetch_roll_result()
|
2024-09-10 10:55:19 +08:00
|
|
|
can_roll = (check_roll() == 1)
|
|
|
|
all_choice = list(map(lambda x: {'name': x[0], 'label': x[1]}, fetch_all_menu()))
|
|
|
|
return render_template('dinner.html',
|
|
|
|
all_choice=all_choice,
|
|
|
|
menu=menu,
|
|
|
|
summary=summary,
|
2024-09-10 11:31:03 +08:00
|
|
|
total_vote=total_vote,
|
2024-09-10 10:55:19 +08:00
|
|
|
result=result,
|
|
|
|
can_roll=can_roll,
|
|
|
|
last_result=last_result)
|