mirror of
https://github.com/zhaarey/AppleMusicDecrypt.git
synced 2025-10-23 15:11:06 +00:00
feat: more exactly url match
This commit is contained in:
10
src/api.py
10
src/api.py
@@ -246,3 +246,13 @@ async def download_m3u8(m3u8_url: str) -> str:
|
|||||||
async with request_lock:
|
async with request_lock:
|
||||||
resp = await client.get(m3u8_url)
|
resp = await client.get(m3u8_url)
|
||||||
return resp.text
|
return resp.text
|
||||||
|
|
||||||
|
|
||||||
|
@alru_cache
|
||||||
|
@retry(retry=retry_if_exception_type(
|
||||||
|
(httpx.TimeoutException, httpcore.ConnectError, SSLError, FileNotFoundError, httpcore.RemoteProtocolError)),
|
||||||
|
stop=stop_after_attempt(5),
|
||||||
|
before_sleep=before_sleep_log(logger, logging.WARN))
|
||||||
|
async def get_real_url(url: str):
|
||||||
|
req = await client.get(url, follow_redirects=True, headers={"User-Agent": user_agent_browser})
|
||||||
|
return str(req.url)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from prompt_toolkit import PromptSession, print_formatted_text, ANSI
|
|||||||
from prompt_toolkit.patch_stdout import patch_stdout
|
from prompt_toolkit.patch_stdout import patch_stdout
|
||||||
|
|
||||||
from src.adb import Device
|
from src.adb import Device
|
||||||
from src.api import get_token, init_client_and_lock, upload_m3u8_to_api, get_song_info
|
from src.api import get_token, init_client_and_lock, upload_m3u8_to_api, get_song_info, get_real_url
|
||||||
from src.config import Config
|
from src.config import Config
|
||||||
from src.rip import rip_song, rip_album, rip_artist, rip_playlist
|
from src.rip import rip_song, rip_album, rip_artist, rip_playlist
|
||||||
from src.types import GlobalAuthParams
|
from src.types import GlobalAuthParams
|
||||||
@@ -91,6 +91,12 @@ class NewInteractiveShell:
|
|||||||
|
|
||||||
async def do_download(self, raw_url: str, codec: str, force_download: bool, include: bool = False):
|
async def do_download(self, raw_url: str, codec: str, force_download: bool, include: bool = False):
|
||||||
url = AppleMusicURL.parse_url(raw_url)
|
url = AppleMusicURL.parse_url(raw_url)
|
||||||
|
if not url:
|
||||||
|
real_url = await get_real_url(raw_url)
|
||||||
|
url = AppleMusicURL.parse_url(real_url)
|
||||||
|
if not url:
|
||||||
|
logger.error("Illegal URL!")
|
||||||
|
return
|
||||||
available_device = await self._get_available_device(url.storefront)
|
available_device = await self._get_available_device(url.storefront)
|
||||||
global_auth_param = GlobalAuthParams.from_auth_params_and_token(available_device.get_auth_params(),
|
global_auth_param = GlobalAuthParams.from_auth_params_and_token(available_device.get_auth_params(),
|
||||||
self.anonymous_access_token)
|
self.anonymous_access_token)
|
||||||
|
|||||||
13
src/url.py
13
src/url.py
@@ -1,5 +1,6 @@
|
|||||||
from urllib.parse import urlparse, parse_qs
|
from urllib.parse import urlparse, parse_qs
|
||||||
|
|
||||||
|
import regex
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
@@ -18,17 +19,19 @@ class AppleMusicURL(BaseModel):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def parse_url(cls, url: str):
|
def parse_url(cls, url: str):
|
||||||
|
if not regex.match(r"https://music.apple.com/(.{2})/(song|album|playlist|artist).*/(pl.*|\d*)", url):
|
||||||
|
return None
|
||||||
parsed_url = urlparse(url)
|
parsed_url = urlparse(url)
|
||||||
paths = parsed_url.path.split("/")
|
paths = parsed_url.path.split("/")
|
||||||
storefront = paths[1]
|
storefront = paths[1]
|
||||||
url_type = paths[2]
|
url_type = paths[2]
|
||||||
match url_type:
|
match url_type:
|
||||||
case URLType.Song:
|
case URLType.Song:
|
||||||
url_id = paths[4]
|
url_id = paths[-1]
|
||||||
return Song(url=url, storefront=storefront, id=url_id, type=URLType.Song)
|
return Song(url=url, storefront=storefront, id=url_id, type=URLType.Song)
|
||||||
case URLType.Album:
|
case URLType.Album:
|
||||||
if not parsed_url.query:
|
if not parsed_url.query:
|
||||||
url_id = paths[4]
|
url_id = paths[-1]
|
||||||
return Album(url=url, storefront=storefront, id=url_id, type=URLType.Album)
|
return Album(url=url, storefront=storefront, id=url_id, type=URLType.Album)
|
||||||
else:
|
else:
|
||||||
url_query = parse_qs(parsed_url.query)
|
url_query = parse_qs(parsed_url.query)
|
||||||
@@ -36,13 +39,13 @@ class AppleMusicURL(BaseModel):
|
|||||||
url_id = url_query.get("i")[0]
|
url_id = url_query.get("i")[0]
|
||||||
return Song(url=url, storefront=storefront, id=url_id, type=URLType.Song)
|
return Song(url=url, storefront=storefront, id=url_id, type=URLType.Song)
|
||||||
else:
|
else:
|
||||||
url_id = paths[4]
|
url_id = paths[-1]
|
||||||
return Album(url=url, storefront=storefront, id=url_id, type=URLType.Album)
|
return Album(url=url, storefront=storefront, id=url_id, type=URLType.Album)
|
||||||
case URLType.Artist:
|
case URLType.Artist:
|
||||||
url_id = paths[4]
|
url_id = paths[-1]
|
||||||
return Artist(url=url, storefront=storefront, id=url_id, type=URLType.Artist)
|
return Artist(url=url, storefront=storefront, id=url_id, type=URLType.Artist)
|
||||||
case URLType.Playlist:
|
case URLType.Playlist:
|
||||||
url_id = paths[4]
|
url_id = paths[-1]
|
||||||
return Playlist(url=url, storefront=storefront, id=url_id, type=URLType.Playlist)
|
return Playlist(url=url, storefront=storefront, id=url_id, type=URLType.Playlist)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user