Skip to content

Commit 9a2a33b

Browse files
committed
Version 1.6.17
QoL: Format code with `black`
1 parent 468e0ff commit 9a2a33b

22 files changed

+1371
-539
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
![Logo](https://github.com/greats3an/pyncm/raw/master/demos/_logo.png)
22

33
# PyNCM
4+
[![Windows Build](https://github.com/mos9527/pyncm/actions/workflows/build-and-publish.yml/badge.svg)](https://github.com/mos9527/pyncm/blob/main/.github/workflows/build-and-publish.yml) [![Releases](https://img.shields.io/github/downloads/mos9527/pyncm/total.svg)](https://GitHub.com/mos9527/pyncm/releases/) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
5+
46
第三方网易云音乐 Python API 及个人音乐库离线转储工具
57

68
**注意** : 异步使用,请移步 [`async` 分支](https://github.com/mos9527/pyncm/tree/async)

demos/__init__.py

+17-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import importlib
2-
import sys,os
2+
import sys, os
3+
4+
IS_FIRSTTIME = sys.path[0] != "."
35

4-
IS_FIRSTTIME = sys.path[0] != '.'
56

67
def assert_dep(name):
78
assert importlib.util.find_spec(name), "需要安装 %s" % name
@@ -10,14 +11,19 @@ def assert_dep(name):
1011
def login():
1112
import inquirer
1213
import demos.手机登录 as 手机登录, 二维码登录
14+
1315
class 匿名登陆:
1416
@staticmethod
1517
def login():
1618
from pyncm.apis.login import LoginViaAnonymousAccount
19+
1720
return LoginViaAnonymousAccount()
18-
methods = {"手机登录": 手机登录, "二维码登录": 二维码登录,"匿名登陆": 匿名登陆}
21+
22+
methods = {"手机登录": 手机登录, "二维码登录": 二维码登录, "匿名登陆": 匿名登陆}
1923
assert methods[
20-
inquirer.prompt([inquirer.List("method", message="登陆方法", choices=methods)])["method"]
24+
inquirer.prompt([inquirer.List("method", message="登陆方法", choices=methods)])[
25+
"method"
26+
]
2127
].login(), "登录失败"
2228
from pyncm import GetCurrentSession
2329

@@ -35,8 +41,10 @@ def login():
3541
# Find pyncm from working directories first,
3642
if IS_FIRSTTIME:
3743
import inquirer
38-
if inquirer.confirm('使用调试模式'):
39-
os.environ['PYNCM_DEBUG'] = 'DEBUG'
40-
sys.path.insert(0,'.')
41-
from pyncm import __version__,__file__
42-
print("PyNCM %s" % __version__,__file__)
44+
45+
if inquirer.confirm("使用调试模式"):
46+
os.environ["PYNCM_DEBUG"] = "DEBUG"
47+
sys.path.insert(0, ".")
48+
from pyncm import __version__, __file__
49+
50+
print("PyNCM %s" % __version__, __file__)

demos/云盘上传.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import hashlib, os
22
from __init__ import login
33

4+
45
def md5sum(file):
56
md5sum = hashlib.md5()
67
with open(file, "rb") as f:
@@ -60,7 +61,7 @@ def upload_one(path):
6061
print("发布结果", publish_result)
6162

6263

63-
if __name__ == "__main__":
64+
if __name__ == "__main__":
6465
assert login(), "登录失败"
6566
# login via phone,may change as you like
6667
upload_one(input("文件路径:"))

demos/手机登录.py

+29-15
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,53 @@
1-
from pyncm.apis.login import LoginViaCellphone,SetSendRegisterVerifcationCodeViaCellphone,GetRegisterVerifcationStatusViaCellphone
2-
from pyncm import GetCurrentSession,DumpSessionAsString, LoadSessionFromString, SetCurrentSession
1+
from pyncm.apis.login import (
2+
LoginViaCellphone,
3+
SetSendRegisterVerifcationCodeViaCellphone,
4+
GetRegisterVerifcationStatusViaCellphone,
5+
)
6+
from pyncm import (
7+
GetCurrentSession,
8+
DumpSessionAsString,
9+
LoadSessionFromString,
10+
SetCurrentSession,
11+
)
312
from pprint import pprint
413

14+
515
def login():
616
import inquirer
17+
718
query = inquirer.prompt(
819
[
9-
inquirer.Text("phone", message="手机号"),
20+
inquirer.Text("phone", message="手机号"),
1021
inquirer.Text("ctcode", message="国家代码(默认86)"),
1122
]
1223
)
13-
phone,ctcode = query["phone"], query["ctcode"] or 86
14-
if inquirer.confirm('使用手机验证码登陆?'):
15-
result = SetSendRegisterVerifcationCodeViaCellphone(phone,ctcode)
16-
if not result.get('code',0) == 200:
24+
phone, ctcode = query["phone"], query["ctcode"] or 86
25+
if inquirer.confirm("使用手机验证码登陆?"):
26+
result = SetSendRegisterVerifcationCodeViaCellphone(phone, ctcode)
27+
if not result.get("code", 0) == 200:
1728
pprint(result)
1829
else:
19-
print('[-] 已发送验证码')
30+
print("[-] 已发送验证码")
2031
while True:
2132
captcha = inquirer.text("输入验证码")
22-
verified = GetRegisterVerifcationStatusViaCellphone(phone,captcha,ctcode)
33+
verified = GetRegisterVerifcationStatusViaCellphone(phone, captcha, ctcode)
2334
pprint(verified)
24-
if verified.get('code',0) == 200:
25-
print('[-] 验证成功')
35+
if verified.get("code", 0) == 200:
36+
print("[-] 验证成功")
2637
break
27-
result = LoginViaCellphone(phone,captcha=captcha,ctcode=ctcode)
38+
result = LoginViaCellphone(phone, captcha=captcha, ctcode=ctcode)
2839
pprint(result)
2940
else:
3041
password = inquirer.password("输入密码")
31-
result = LoginViaCellphone(phone,password=password,ctcode=ctcode)
42+
result = LoginViaCellphone(phone, password=password, ctcode=ctcode)
3243
pprint(result)
33-
print('[!] 登录态 Session:',DumpSessionAsString(GetCurrentSession()))
34-
print('[-] 此后可通过 SetCurrentSession(LoadSessionFromString("PYNCMe...")) 恢复当前登录态')
44+
print("[!] 登录态 Session:", DumpSessionAsString(GetCurrentSession()))
45+
print(
46+
'[-] 此后可通过 SetCurrentSession(LoadSessionFromString("PYNCMe...")) 恢复当前登录态'
47+
)
3548
return True
3649

50+
3751
if __name__ == "__main__":
3852
print("[-] 登录测试")
3953
assert login(), "登陆失败"

demos/歌单同步.py

+24-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
'''
1+
"""
22
以下 .pyncm 即为你保存的登陆凭据
33
---
44
使用例 : 同步个人创建的歌单到`NetEase/[专辑名]`
@@ -7,50 +7,60 @@
77
python ./demos/歌单同步.py --load .pyncm --quality hires --output NetEase/{album} --user-bookmarks --save-m3u NetEase/PLAYLIST.m3u
88
使用例 : 同步某一歌单到`NetEase/[专辑名]`
99
python ./demos/歌单同步.py --load .pyncm --quality hires --output NetEase/{album} https://music.163.com/playlist?id=988690134
10-
'''
10+
"""
11+
1112
from sys import argv
12-
from os import walk,path,remove
13-
from pyncm.__main__ import parse_args ,PLACEHOLDER_URL,__main__
14-
from pyncm import GetCurrentSession,SetCurrentSession,LoadSessionFromString
13+
from os import walk, path, remove
14+
from pyncm.__main__ import parse_args, PLACEHOLDER_URL, __main__
15+
from pyncm import GetCurrentSession, SetCurrentSession, LoadSessionFromString
1516
from pyncm.utils.helper import UserHelper
17+
1618
# 指定 quit_on_empty_args=False 便于传入空 ID
1719
args, _ = parse_args(quit_on_empty_args=False)
1820
print("[-] 读取登录信息 : %s" % args.load)
1921
SetCurrentSession(LoadSessionFromString(open(args.load).read()))
2022
print("[*] 用户 : %s" % UserHelper(GetCurrentSession().uid).UserName)
2123
try:
2224
# 使用未模板化的最高级目录做输出目录起点
23-
output = args.output[:args.output.index('{')]
25+
output = args.output[: args.output.index("{")]
2426
except IndexError:
2527
output = args.output
2628
print("[*] 输出文件夹起点 : %s" % output)
29+
30+
2731
def normalize(path):
28-
return path.replace('\\','/') # 统一 Windows/Unix 路径格式
32+
return path.replace("\\", "/") # 统一 Windows/Unix 路径格式
33+
34+
2935
# 平面化目录结构,准备后期比对
30-
file_tree = [normalize(path.join(root,file)) for root, dirs, files in walk(output,topdown=False) for file in files]
36+
file_tree = [
37+
normalize(path.join(root, file))
38+
for root, dirs, files in walk(output, topdown=False)
39+
for file in files
40+
]
3141
# 调用 pyncm 下载
3242
if args.url == PLACEHOLDER_URL:
3343
# 未填入 ID 则使用用户本人歌单
34-
argv.append('https://music.163.com/#/user/home?id=%s' % GetCurrentSession().uid)
44+
argv.append("https://music.163.com/#/user/home?id=%s" % GetCurrentSession().uid)
3545
argv.append("--no-overwrite")
3646
# 不覆写已存在歌曲
3747
# argv 传参,调用 __main__ 即可
3848
queuedTasks, failed_ids = __main__(return_tasks=True)
3949
# 无视拓展名的文件白名单
4050
file_tree_whitelist = [normalize(task.save_as) for task in queuedTasks]
4151
# 只删除这些拓展名的文件
42-
extension_blacklist = {'m4a','mp3','flac','ogg','lrc','ass'}
52+
extension_blacklist = {"m4a", "mp3", "flac", "ogg", "lrc", "ass"}
4353
for file in file_tree:
4454
delete_flag = True
4555
for file_whitelist in file_tree_whitelist:
4656
if file.startswith(file_whitelist):
4757
delete_flag = False
4858
break
4959
if delete_flag:
50-
ext = file.split('.')[-1].lower()
51-
if ext in extension_blacklist:
60+
ext = file.split(".")[-1].lower()
61+
if ext in extension_blacklist:
5262
try:
53-
print('[!] 删除 %s' % file)
63+
print("[!] 删除 %s" % file)
5464
remove(file)
5565
except Exception as e:
56-
print('[!!] 删除 %s 失败: %s' % (file,e))
66+
print("[!!] 删除 %s 失败: %s" % (file, e))

demos/足迹伪装.py

+23-17
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__desc__ = '''user.SetWeblog API 功能演示
1+
__desc__ = """user.SetWeblog API 功能演示
22
33
摘自 https://github.com/Binaryify/NeteaseCloudMusicApi
44
@@ -13,24 +13,30 @@
1313
接口地址 : /scrobble
1414
1515
调用例子 : /scrobble?id=518066366&sourceid=36780169&time=291
16-
'''
16+
"""
1717
from __init__ import login
18+
1819
assert login(), "登录失败"
1920
from pyncm.apis.user import SetWeblog
2021
from pprint import pprint
22+
2123
print(__desc__)
22-
pprint(SetWeblog(
23-
[{
24-
'action': 'play',
25-
'json': {
26-
'download': 0,
27-
'end': 'playend',
28-
'id': input('歌曲 ID:'),
29-
'sourceId': input('来源 ID:'),
30-
'time': input('时长:') or 300,
31-
'type': 'song',
32-
'wifi': 0,
33-
'source' : 'list',
34-
}
35-
}]
36-
))
24+
pprint(
25+
SetWeblog(
26+
[
27+
{
28+
"action": "play",
29+
"json": {
30+
"download": 0,
31+
"end": "playend",
32+
"id": input("歌曲 ID:"),
33+
"sourceId": input("来源 ID:"),
34+
"time": input("时长:") or 300,
35+
"type": "song",
36+
"wifi": 0,
37+
"source": "list",
38+
},
39+
}
40+
]
41+
)
42+
)

pyncm.tests.py

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import unittest,logging
1+
import unittest, logging
22
import pyncm, pyncm.apis
3+
34
logging.basicConfig(level=0)
45
# Account from https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/test/login.test.js
56
pyncm.SetCurrentSession(
@@ -8,30 +9,31 @@
89
)
910
)
1011

12+
1113
class APITest(unittest.TestCase):
1214
def test_set_like(self):
1315
self.assertEqual(
14-
pyncm.apis.track.SetLikeTrack(31140560, like=True).get("code", 0),200
16+
pyncm.apis.track.SetLikeTrack(31140560, like=True).get("code", 0), 200
1517
)
1618

1719
def test_set_like_revert(self):
1820
self.assertEqual(
19-
pyncm.apis.track.SetLikeTrack(31140560, like=False).get("code", 0) , 200
21+
pyncm.apis.track.SetLikeTrack(31140560, like=False).get("code", 0), 200
2022
)
2123

2224
def test_manipulate_playlist(self):
2325
playlist = pyncm.apis.playlist.SetCreatePlaylist("Playlist")
24-
self.assertEqual(playlist.get("code", 0) , 200, "Cannot create Playlist")
26+
self.assertEqual(playlist.get("code", 0), 200, "Cannot create Playlist")
2527
self.assertEqual(
2628
pyncm.apis.playlist.SetManipulatePlaylistTracks(
2729
31140560, playlist.get("id", 0)
28-
).get("code", 0)
29-
, 200,
30+
).get("code", 0),
31+
200,
3032
"Cannot add track to playlist created",
3133
)
3234
self.assertEqual(
33-
pyncm.apis.playlist.SetRemovePlaylist(playlist.get("id", 0)).get("code", 0)
34-
, 200,
35+
pyncm.apis.playlist.SetRemovePlaylist(playlist.get("id", 0)).get("code", 0),
36+
200,
3537
"Cannot remove track from playlist created",
3638
)
3739

0 commit comments

Comments
 (0)