thief_music_api/api.py

292 lines
9.6 KiB
Python
Raw Normal View History

2023-07-25 18:39:59 +08:00
import fastapi
from fastapi.security import OAuth2PasswordRequestForm
from fastapi_login.exceptions import InvalidCredentialsException
from datetime import timedelta
2023-07-25 18:39:59 +08:00
import requests
import uvicorn
from fastapi import Depends
2023-07-25 18:39:59 +08:00
from fastapi import FastAPI
2023-07-30 21:13:38 +08:00
from fastapi.middleware.cors import CORSMiddleware
from fastapi_login import LoginManager
from server.user_server import *
from server.rank_data import *
from server.music_server import *
2023-07-25 18:39:59 +08:00
env = os.environ
app = FastAPI()
2023-07-30 21:13:38 +08:00
# 配置 CORS 中间件
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 允许所有来源,可以根据需求进行配置
allow_credentials=True,
allow_methods=["*"], # 允许所有请求方法
allow_headers=["*"], # 允许所有请求头
)
SECRET = os.urandom(24).hex()
manager = LoginManager(SECRET, token_url='/auth/token', use_cookie=False)
2023-07-25 18:39:59 +08:00
try:
# mysql数据配置
con = pymysql.connect(host=mysql_host, user=mysql_user, password=mysql_password, port=mysql_port,
charset="utf8", database=mysql_database)
# cursor = con.cursor()
except Exception as e:
print(e)
print("数据库连接失败")
@manager.user_loader()
def load_user(username: int):
2023-08-04 19:27:30 +08:00
"""
获取用户信息
:param username:
:return:
2023-08-04 19:27:30 +08:00
"""
try:
with con.cursor() as cursor:
cursor.execute("SELECT * FROM User WHERE username = %s", (username,))
user = cursor.fetchone()
2023-08-04 19:27:30 +08:00
if user:
user_dict = dict(username=user[1], password=user[3])
return user_dict
else:
return None
except Exception as e:
print(e)
return None
2023-08-04 19:27:30 +08:00
# @app.get('/auth/cookie')
# def auth(response: Response, user=Depends(manager)):
# """
# 通过cookie验证用户
# :param response:
# :param user:
# :return:
# """
# # 查询用户信息
# cursor.execute("SELECT * FROM User WHERE email = %s", (user['sub'],))
# user = cursor.fetchone()
# # 生成token
# token = manager.create_access_token(
# data=dict(sub=user[2])
# )
# manager.set_cookie(response, token)
# return response
2023-08-04 19:27:30 +08:00
@app.post('/auth/get_token')
def get_token(data: OAuth2PasswordRequestForm = Depends()):
username = data.username
password = md5(data.password)
2023-08-04 19:27:30 +08:00
user = load_user(username) # we are using the same function to retrieve the user
if not user:
raise InvalidCredentialsException # you can also use your own HTTPException
elif password != user['password']:
raise InvalidCredentialsException
access_token = manager.create_access_token(
data=dict(sub=username),
expires=timedelta(hours=12)
)
return {'access_token': access_token, 'token_type': 'bearer'}
# 验证Token
@app.get('/token/verify_user')
def get_current_user(current_user=Depends(manager.get_current_user)):
if current_user:
return {"status":200 ,"success": True, "message": "Validated successfully"}
else:
return {"status":400 ,"success": False, "message": "Invalid token"}
# @app.get('/protected')
# def protected_route(user=Depends(manager)):
# return "验证通过"
# 注册
@app.post("/user/register")
async def user_register(
username: str = fastapi.Query(..., description="用户名"),
password: str = fastapi.Query(..., description="密码"),
email: str = fastapi.Query(None, description="邮箱")):
2023-08-04 19:27:30 +08:00
"""
注册
:param username:
:param password:
:param email:
:return:
2023-08-04 19:27:30 +08:00
"""
create_user(username, password)
# 获取Token
token_info = get_token(OAuth2PasswordRequestForm(username=username, password=password))
return {"success": True, "message": "注册成功", "token": token_info}
2023-08-04 19:27:30 +08:00
# 登陆
@app.post("/user/login")
async def user_login(
username: str = fastapi.Query(..., description="用户名"),
password: str = fastapi.Query(..., description="密码")):
"""
登陆并获取Token
:param username:
:param password:
:return:
"""
# 请求auth/token接口获取token
token_info = get_token(OAuth2PasswordRequestForm(username=username, password=password))
login_info = user_login(username, password)
if login_info:
return {"success": True, "message": "登陆成功", "token": token_info}
else:
return {"success": False, "message": "登陆失败"}
2023-08-04 19:27:30 +08:00
2023-07-30 21:03:11 +08:00
# 榜单获取
2023-08-06 18:42:48 +08:00
@app.get("/get_rank")
2023-07-30 21:03:11 +08:00
async def get_rank(
rank_id: str = fastapi.Query(..., description="榜单类型"),
current_user=Depends(manager.get_current_user)):
2023-07-30 21:03:11 +08:00
"""
:param rank_id:
19723756 云音乐飙升榜
3779629 云音乐新歌榜
3778678 云音乐热歌榜
2884035 云音乐原创榜
:return:
"""
2023-08-04 19:38:09 +08:00
headers = {
"Referer": "https://music.163.com/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
" AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36"
2023-08-04 19:38:09 +08:00
}
2023-07-30 21:03:11 +08:00
url = f"https://music.163.com/api/playlist/detail?id={rank_id}"
2023-08-06 18:42:48 +08:00
# 缓存文件不存在,从网络获取榜单数据
2023-08-04 19:38:09 +08:00
response = requests.get(url, headers=headers)
2023-08-06 18:42:48 +08:00
# 如果请求code为-447 那么继续返回json
if response.status_code == -447:
return {"message": "response code is -447, local json data", "data": response.json()}
2023-08-06 18:42:48 +08:00
else:
# 检测是否含有带rank_id的缓存文件
cached_data = read_cache(rank_id)
if cached_data:
return {"message": "local json data", "data": cached_data}
2023-08-06 18:42:48 +08:00
# 将榜单数据写入缓存文件
write_cache(rank_id, response.json())
print(response.json())
2023-08-04 19:38:09 +08:00
data = response.json()
return {"message": "Request Netease Cloud And Local Cache JSON Success", "data": data}
2023-08-06 18:42:48 +08:00
2023-07-25 18:39:59 +08:00
@app.get("/search_song_by_name")
async def search_song_by_name(
name: str = fastapi.Query(..., description="歌曲名称"),
# current_user=Depends(manager.get_current_user)
):
2023-07-25 18:39:59 +08:00
payload = {
"input": name,
"filter": "name",
"type": "netease", # netease, tencent, kugou, xiami, baidu
"page": 1
}
url = "https://sunpma.com/other/musicss/"
# Headers for the POST request
headers = {
"Accept": "application/json, text/javascript, */*; q=0.01",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Origin": "https://sunpma.com",
"Referer": f"https://sunpma.com/other/musicss/?name={payload['input']}&type={payload['type']}",
"Sec-Ch-Ua": "\"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"114\", \"Google Chrome\";v=\"114\"",
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": "\"macOS\"",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
"X-Requested-With": "XMLHttpRequest"
}
# 将所有 headers 的值用 'utf-8' 进行编码
headers = {key: value.encode('utf-8') for key, value in headers.items()}
# Making the POST request
response = requests.post(url, data=payload, headers=headers)
# Check if the request was successful (status code 200)
if response.status_code == 200:
# Parse the response JSON data
data = response.json()
return {"message": "success", "data": data}
else:
print(f"Failed to get data. Status code: {response.status_code}")
return {"message": "failed", "data": []}
2023-07-28 12:53:34 +08:00
2023-07-25 18:39:59 +08:00
# 根据歌曲id搜索歌曲
@app.get("/search_song_by_id")
async def search_song_by_id(
music_id: str = fastapi.Query(..., description="歌曲id"),
# current_user=Depends(manager.get_current_user)
):
2023-07-25 18:39:59 +08:00
payload = {
"input": music_id,
2023-07-25 18:39:59 +08:00
"filter": "id",
"type": "netease", # netease, tencent, kugou, xiami, baidu
"page": 1
}
headers = {
"Accept": "application/json, text/javascript, */*; q=0.01",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Origin": "https://sunpma.com",
"Referer": f"https://sunpma.com/other/musicss/?id={payload['input']}&type=netease",
"Sec-Ch-Ua": "\"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"114\", \"Google Chrome\";v=\"114\"",
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": "\"macOS\"",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
"X-Requested-With": "XMLHttpRequest"
}
url = "https://sunpma.com/other/musicss/"
# Making the POST request
response = requests.post(url, data=payload, headers=headers)
# Check if the request was successful (status code 200)
if response.status_code == 200:
# Parse the response JSON data
data = response.json()
print(data)
try:
save_search_music(data)
except Exception as e:
print(e)
2023-07-25 18:39:59 +08:00
return {"message": "success", "data": data}
else:
print(f"Failed to get data. Status code: {response.status_code}")
return {"message": "failed", "data": []}
2023-07-28 12:53:34 +08:00
2023-07-25 18:39:59 +08:00
if __name__ == '__main__':
host = env.get("HOST") if env.get("HOST") is not None else "0.0.0.0"
port = int(env.get("PORT")) if env.get("PORT") is not None else 7888
2023-07-28 12:53:34 +08:00
uvicorn.run(app='api:app', host=host, port=port, reload=True)