diff --git a/.gitignore b/.gitignore index b6e4761..b97131e 100644 --- a/.gitignore +++ b/.gitignore @@ -127,3 +127,5 @@ dmypy.json # Pyre type checker .pyre/ + +.idea/ diff --git a/defs.py b/defs.py new file mode 100644 index 0000000..b74a817 --- /dev/null +++ b/defs.py @@ -0,0 +1,4 @@ +class Music: + def __init__(self, name: str, album: str): + self.name = name + self.album = album diff --git a/main.py b/main.py new file mode 100644 index 0000000..3364c57 --- /dev/null +++ b/main.py @@ -0,0 +1,12 @@ +from fastapi import FastAPI, Query +from utils import get_music + +app = FastAPI() + + +@app.get('/search') +async def search( + *, + keyword: str = Query(..., title="The name of a song") +): + return await get_music(keyword) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..edd608b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +httpx==0.23.0 +pyncm==1.6.8.1 +fastapi~=0.85.0 +starlette~=0.20.4 +uvicorn~=0.18.3 diff --git a/services/apple.py b/services/apple.py new file mode 100644 index 0000000..e132fac --- /dev/null +++ b/services/apple.py @@ -0,0 +1,26 @@ +import contextlib +import httpx + +from typing import List +from defs import Music + +headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_2) " + "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.0 Mobile Safari/537.36"} + + +class Apple: + @staticmethod + async def get(keyword: str) -> List[Music]: + try: + async with httpx.AsyncClient(headers=headers) as client: + req = await client.get(f"https://itunes.apple.com/search?term={keyword}&entity=song&limit=4") + req = req.json() + except Exception: + return [] + if req.get("resultCount", 0) == 0: + return [] + results = [] + for i in req["results"]: + with contextlib.suppress(Exception): + results.append(Music(i["trackName"], i["artworkUrl100"])) + return results diff --git a/services/netease.py b/services/netease.py new file mode 100644 index 0000000..95883e9 --- /dev/null +++ b/services/netease.py @@ -0,0 +1,22 @@ +import contextlib + +from typing import List +from pyncm import GetCurrentSession, apis +from defs import Music + + +class Netease: + @staticmethod + async def get(keyword: str) -> List[Music]: + # 海外用户 + GetCurrentSession().headers["X-Real-IP"] = "118.88.88.88" + try: + req = apis.cloudsearch.GetSearchResult(keyword) + songs = req["result"]["songs"] + except Exception: + return [] + results = [] + for i in songs: + with contextlib.suppress(Exception): + results.append(Music(i["name"], i["al"]["picUrl"].replace("http:", "https:"))) + return results diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..e171868 --- /dev/null +++ b/utils.py @@ -0,0 +1,28 @@ +import contextlib +from typing import List + +from defs import Music +from services import apple, netease + +default_data = {"resultCount": 0, "results": []} + + +def parse_data(data: List[Music]) -> dict: + length = len(data) + if length == 0: + return default_data + results = [{"trackName": i.name, "artworkUrl100": i.album} for i in data] + return {"resultCount": length, "results": results} + + +async def get_music(keyword: str) -> dict: + if not keyword: + return default_data + with contextlib.suppress(Exception): + apple_result = await apple.Apple.get(keyword) + if apple_result: + return parse_data(apple_result) + netease_result = await netease.Netease.get(keyword) + if netease_result: + return parse_data(netease_result) + return default_data diff --git a/vercel.json b/vercel.json new file mode 100644 index 0000000..9414fa7 --- /dev/null +++ b/vercel.json @@ -0,0 +1,4 @@ +{ + "builds": [{ "src": "main.py", "use": "@vercel/python" }], + "routes": [{ "src": "/(.*)", "dest": "main.py" }] +} \ No newline at end of file