Skip to content

Commit aefdc90

Browse files
refactor: format code
1 parent db01b7c commit aefdc90

10 files changed

Lines changed: 101 additions & 97 deletions

File tree

src/api.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,16 @@ def init(self):
7474

7575
@retry(retry=retry_if_exception_type((httpx.HTTPError, SSLError, FileNotFoundError)),
7676
wait=wait_random_exponential(multiplier=1, max=it(Config).download.maxWaitTime),
77-
stop=stop_after_attempt(it(Config).download.retryTime), before_sleep=before_sleep_log(it(GlobalLogger).logger, "WARNING"))
77+
stop=stop_after_attempt(it(Config).download.retryTime),
78+
before_sleep=before_sleep_log(it(GlobalLogger).logger, "WARNING"))
7879
async def _request(self, *args, **kwargs):
7980
async with self.request_lock:
8081
return await self.client.request(*args, **kwargs)
8182

8283
@retry(retry=retry_if_exception_type((httpx.HTTPError, SSLError, FileNotFoundError)),
8384
wait=wait_random_exponential(multiplier=1, max=it(Config).download.maxWaitTime),
84-
stop=stop_after_attempt(it(Config).download.retryTime), before_sleep=before_sleep_log(it(GlobalLogger).logger, "WARNING"))
85+
stop=stop_after_attempt(it(Config).download.retryTime),
86+
before_sleep=before_sleep_log(it(GlobalLogger).logger, "WARNING"))
8587
async def download_song(self, url: str) -> bytes:
8688
async with self.download_lock:
8789
result = BytesIO()
@@ -110,7 +112,8 @@ async def get_album_info(self, album_id: str, storefront: str, lang: str):
110112
return album_info_obj
111113

112114
async def get_album_tracks(self, album_id: str, storefront: str, lang: str, offset: int = 0):
113-
req = await self._request("GET", f"https://amp-api.music.apple.com/v1/catalog/{storefront}/albums/{album_id}/tracks?offset={offset}")
115+
req = await self._request("GET",
116+
f"https://amp-api.music.apple.com/v1/catalog/{storefront}/albums/{album_id}/tracks?offset={offset}")
114117
album_info_obj = AlbumTracks.model_validate(req.json())
115118
tracks = album_info_obj.data
116119
if album_info_obj.next:

src/cmd.py

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import argparse
22
import asyncio
33
import copy
4-
import sys
54
import os
5+
import sys
66

77
import grpc.aio
88
from creart import it
@@ -17,12 +17,10 @@
1717
from src.logger import GlobalLogger
1818
from src.measurer import Measurer
1919
from src.qemu import QemuInstance
20-
from src.measurer import Measurer
21-
from src.qemu import QemuInstance
20+
from src.quality import print_song_quality, print_album_quality, print_playlist_quality, key_to_Headers
2221
from src.rip import Ripper
2322
from src.url import AppleMusicURL, URLType
2423
from src.utils import check_dep, run_sync, safely_create_task, config_outdated
25-
from src.quality import print_song_quality, print_album_quality, print_playlist_quality, key_to_Headers
2624

2725

2826
class InteractiveShell:
@@ -54,21 +52,23 @@ def __init__(self, loop: asyncio.AbstractEventLoop):
5452
loop.run_until_complete(asyncio.sleep(3))
5553
else:
5654
loop.run_until_complete(it(WrapperManager).init(it(Config).instance.url, it(Config).instance.secure))
57-
safely_create_task(it(WrapperManager).decrypt_init(on_success=self.ripper.on_decrypt_success, on_failure=self.ripper.on_decrypt_failed))
55+
safely_create_task(it(WrapperManager).decrypt_init(on_success=self.ripper.on_decrypt_success,
56+
on_failure=self.ripper.on_decrypt_failed))
5857
try:
5958
loop.run_until_complete(self.show_status())
6059
except grpc.aio._call.AioRpcError:
6160
it(GlobalLogger).logger.error("Unable to connect to the wrapper-manager")
6261
sys.exit()
6362

6463
if config_outdated():
65-
it(GlobalLogger).logger.warning("The configuration file is out of date. Please refer to config.example.toml to update it")
64+
it(GlobalLogger).logger.warning(
65+
"The configuration file is out of date. Please refer to config.example.toml to update it")
6666

6767
self.parser = argparse.ArgumentParser(exit_on_error=False)
6868
subparser = self.parser.add_subparsers()
6969
download_parser = subparser.add_parser("download", aliases=["dl"])
7070
quality_parser = subparser.add_parser("quality", aliases=["qa"])
71-
download_parser.add_argument("url", nargs='*', type=str)
71+
download_parser.add_argument("url", nargs='*', type=str)
7272
download_parser.add_argument("-c", "--codec",
7373
choices=["alac", "ec3", "aac", "aac-binaural", "aac-downmix", "aac-legacy", "ac3"],
7474
default="alac")
@@ -77,8 +77,8 @@ def __init__(self, loop: asyncio.AbstractEventLoop):
7777
download_parser.add_argument("-l", "--language", default=it(Config).region.language, action="store")
7878
download_parser.add_argument("--include-participate-songs", default=False, dest="include", action="store_true")
7979

80-
quality_parser.add_argument("url", nargs='*', type=str)
81-
quality_parser.add_argument("-i","--invert", default=False, action="store_true")
80+
quality_parser.add_argument("url", nargs='*', type=str)
81+
quality_parser.add_argument("-i", "--invert", default=False, action="store_true")
8282
quality_parser.add_argument("--codec-id", default=True, action="store_false")
8383
quality_parser.add_argument("--codec", default=True, action="store_false")
8484
quality_parser.add_argument("--bitrate", default=True, action="store_false")
@@ -99,7 +99,8 @@ async def show_status(self):
9999
it(WrapperManager).status.cache_invalidate()
100100
st_resp = await it(WrapperManager).status()
101101
if not st_resp.regions:
102-
it(GlobalLogger).logger.error("The currently used wrapper-manager instance has no available account. Please execute login command to log in.")
102+
it(GlobalLogger).logger.error(
103+
"The currently used wrapper-manager instance has no available account. Please execute login command to log in.")
103104
it(GlobalLogger).logger.info(f"Regions available on wrapper-manager instance: {', '.join(st_resp.regions)}")
104105

105106
async def handle_batch_mode(self, args, cmds):
@@ -108,16 +109,17 @@ async def handle_batch_mode(self, args, cmds):
108109
self.batch_mode = True
109110
self.batch_args = args
110111
self.batch_command = cmds[0]
111-
it(GlobalLogger).logger.info("Entering batch mode. Enter one or more URLs per line (space-separated), type 'exit' to quit")
112+
it(GlobalLogger).logger.info(
113+
"Entering batch mode. Enter one or more URLs per line (space-separated), type 'exit' to quit")
112114
except:
113115
pass
114-
116+
115117
async def batch_mode_parser(self, cmds: str):
116-
args=self.batch_args
117-
args.url=copy.deepcopy(cmds)
118-
if cmds[0]!="exit":
118+
args = self.batch_args
119+
args.url = copy.deepcopy(cmds)
120+
if cmds[0] != "exit":
119121
cmds[0] = self.batch_command
120-
return cmds,args
122+
return cmds, args
121123

122124
async def command_parser(self, cmd: str):
123125
if not cmd.strip():
@@ -139,15 +141,15 @@ async def command_parser(self, cmd: str):
139141
await self.show_status()
140142
case "exit":
141143
if self.batch_mode:
142-
self.batch_mode=False
144+
self.batch_mode = False
143145
it(GlobalLogger).logger.info("Batch mode exited. Returning to normal command mode.")
144146
else:
145147
self.handle_exit()
146148
case "quality" | "qa":
147-
safely_create_task(self.do_quality(args.url, args))
148-
149+
safely_create_task(self.do_quality(args.url, args))
149150

150-
async def do_download(self, raw_urls: list[str], codec: str, force_download: bool, language: str, include: bool = False):
151+
async def do_download(self, raw_urls: list[str], codec: str, force_download: bool, language: str,
152+
include: bool = False):
151153
for raw_url in raw_urls:
152154
url = AppleMusicURL.parse_url(raw_url)
153155
if not url:
@@ -158,18 +160,22 @@ async def do_download(self, raw_urls: list[str], codec: str, force_download: boo
158160
continue
159161
match url.type:
160162
case URLType.Song:
161-
safely_create_task(self.ripper.rip_song(url, codec, Flags(force_save=force_download, language=language)))
163+
safely_create_task(
164+
self.ripper.rip_song(url, codec, Flags(force_save=force_download, language=language)))
162165
case URLType.Album:
163-
safely_create_task(self.ripper.rip_album(url, codec, Flags(force_save=force_download, language=language)))
166+
safely_create_task(
167+
self.ripper.rip_album(url, codec, Flags(force_save=force_download, language=language)))
164168
case URLType.Artist:
165-
safely_create_task(self.ripper.rip_artist(url, codec, Flags(force_save=force_download, language=language,
166-
include_participate_in_works=include)))
169+
safely_create_task(
170+
self.ripper.rip_artist(url, codec, Flags(force_save=force_download, language=language,
171+
include_participate_in_works=include)))
167172
case URLType.Playlist:
168-
safely_create_task(self.ripper.rip_playlist(url, codec, Flags(force_save=force_download, language=language)))
173+
safely_create_task(
174+
self.ripper.rip_playlist(url, codec, Flags(force_save=force_download, language=language)))
169175
case _:
170176
it(GlobalLogger).logger.error(f"Unsupported URLType - {raw_url}")
171-
continue
172-
177+
continue
178+
173179
async def do_quality(self, raw_urls: list[str], args):
174180
all_fields = list(key_to_Headers.keys())
175181
show_fields = []
@@ -246,7 +252,8 @@ def completer(self):
246252

247253
def handle_exit(self):
248254
if it(Measurer).tasks_count() > 0:
249-
it(GlobalLogger).logger.info("There is still {} tasks, do you really want to exit? (y/N)".format(it(Measurer).tasks_count()))
255+
it(GlobalLogger).logger.info(
256+
"There is still {} tasks, do you really want to exit? (y/N)".format(it(Measurer).tasks_count()))
250257
response = input().strip().lower()
251258
if response != 'y':
252259
return
@@ -255,7 +262,8 @@ def handle_exit(self):
255262
os._exit(0)
256263

257264
async def handle_command(self):
258-
session = PromptSession("> ", bottom_toolbar=self.bottom_toolbar, completer=self.completer(), refresh_interval=1)
265+
session = PromptSession("> ", bottom_toolbar=self.bottom_toolbar, completer=self.completer(),
266+
refresh_interval=1)
259267

260268
while True:
261269
try:
@@ -301,11 +309,10 @@ async def logout_flow(self):
301309
it(GlobalLogger).logger.info("Logout Success!")
302310
it(WrapperManager).status.cache_invalidate()
303311

304-
305312
async def start(self):
306313
with patch_stdout():
307314
try:
308315
await self.handle_command()
309316
finally:
310317
if it(Config).localInstance.enable:
311-
self.localInstance.terminate()
318+
self.localInstance.terminate()

src/logger.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ def not_exist(self):
7474
f"Unable to download {self.item_type}. This {self.item_type} does not exist in all available storefronts")
7575

7676
def language_not_exist(self, region: str, current_language: str, default_language: str):
77-
self.logger.warning(f"Selected language {current_language} does not exist in region {region.upper()}, falling back to {default_language}")
77+
self.logger.warning(
78+
f"Selected language {current_language} does not exist in region {region.upper()}, falling back to {default_language}")
7879

7980
def already_exist(self):
8081
self.logger.info(f"Song already exists")
@@ -113,4 +114,4 @@ def selected_codec(self, selected_codec):
113114
self.logger.info(f"Selected codec: {selected_codec}")
114115

115116
def codec_alternative(self):
116-
self.logger.warning("Unable to find the specified audio, switched to another audio codec")
117+
self.logger.warning("Unable to find the specified audio, switched to another audio codec")

src/metadata.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
from typing import Optional, Dict, List
22

3-
from creart import it
43
from mutagen.mp4 import MP4Cover
54
from pydantic import BaseModel
65

7-
86
from src.models import AlbumMeta
97
from src.models.song_data import Datum
108
from src.utils import ttml_convent, count_total_track_and_disc
@@ -167,7 +165,6 @@ def _rating(content_rating: Optional[str]) -> int:
167165
def set_lyrics(self, lyrics: str):
168166
self.lyrics = lyrics
169167

170-
171168
def set_playlist_index(self, index: int):
172169
self.playlist_index = index
173170

src/mp4.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ def encapsulate(song_info: SongInfo, decrypted_media: bytes, atmos_convent: bool
203203

204204

205205
def write_metadata(song: bytes, metadata: SongMetadata, embed_metadata: list[str],
206-
cover_format: str, params: dict[str, Any]) -> bytes:
206+
cover_format: str, params: dict[str, Any]) -> bytes:
207207
tmp_dir = TemporaryDirectory()
208208
name = uuid.uuid4().hex
209209
song_name = Path(tmp_dir.name) / Path(f"{name}.m4a")

src/qemu.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class QGAClient:
4040
reader: asyncio.StreamReader
4141
writer: asyncio.StreamWriter
4242

43-
@retry(retry=retry_if_exception_type((asyncio.TimeoutError)),
43+
@retry(retry=retry_if_exception_type(asyncio.TimeoutError),
4444
wait=wait_random_exponential(multiplier=1, max=it(Config).download.maxWaitTime),
4545
stop=stop_after_attempt(8), before_sleep=before_sleep_log(it(GlobalLogger).logger, "WARNING"))
4646
async def init(self):
@@ -66,7 +66,8 @@ async def read_file(self, path: str):
6666

6767
async def write_file(self, path: str, content: str):
6868
fp = await self.send_cmd("guest-file-open", {"path": path, "mode": "w"})
69-
await self.send_cmd("guest-file-write", {"handle": fp, "buf-b64": base64.standard_b64encode(content.encode()).decode()})
69+
await self.send_cmd("guest-file-write",
70+
{"handle": fp, "buf-b64": base64.standard_b64encode(content.encode()).decode()})
7071
await self.send_cmd("guest-file-close", {"handle": fp})
7172

7273
async def execute(self, path: str, args: list[str]):

src/quality.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@
1414
from src.grpc.manager import WrapperManager
1515

1616
Headers = [
17-
"Codec ID",
18-
"Codec",
19-
"Bitrate",
20-
"Average Bitrate",
21-
"Channels",
22-
"Sample Rate",
17+
"Codec ID",
18+
"Codec",
19+
"Bitrate",
20+
"Average Bitrate",
21+
"Channels",
22+
"Sample Rate",
2323
"Bit Depth"
2424
]
2525

@@ -33,6 +33,7 @@
3333
"bit_depth": "Bit Depth"
3434
}
3535

36+
3637
async def get_available_audio_quality(m3u8_url: str):
3738
parsed_m3u8 = m3u8.loads(await it(WebAPI).download_m3u8(m3u8_url), uri=m3u8_url)
3839
result = []
@@ -47,6 +48,7 @@ async def get_available_audio_quality(m3u8_url: str):
4748
bit_depth=playlist.media[0].extras.get("bit_depth", None)))
4849
return result
4950

51+
5052
async def print_song_quality(url: Song, show_fields: list[str]):
5153
raw_metadata = await it(WebAPI).get_song_info(url.id, url.storefront, it(Config).region.language)
5254
metadata = SongMetadata.parse_from_song_data(raw_metadata)
@@ -62,13 +64,15 @@ async def print_song_quality(url: Song, show_fields: list[str]):
6264
print_formatted_text(f"Available audio qualities for song: {metadata.artist} - {metadata.title}")
6365
print_formatted_text(tabulate(filtered_data, headers=filtered_headers, tablefmt="grid"))
6466

67+
6568
async def print_playlist_quality(url: Playlist, show_fields: list[str]):
6669
playlist_info = await it(WebAPI).get_playlist_info_and_tracks(url.id, url.storefront, it(Config).region.language)
6770
playlist_info = playlist_write_song_index(playlist_info)
6871
for track in playlist_info.data[0].relationships.tracks.data:
6972
song = Song(id=track.id, storefront=url.storefront, url="", type=URLType.Song)
7073
safely_create_task(print_song_quality(song, show_fields))
7174

75+
7276
async def print_album_quality(url: Album, show_fields: list[str]):
7377
album_info = await it(WebAPI).get_album_info(url.id, url.storefront, it(Config).region.language)
7478
for track in album_info.data[0].relationships.tracks.data:

0 commit comments

Comments
 (0)