qqmusic-api-python 0.1.7__tar.gz → 0.1.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/PKG-INFO +12 -6
  2. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/README.md +10 -4
  3. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/pyproject.toml +5 -2
  4. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/__init__.py +3 -2
  5. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/album.py +8 -4
  6. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/data/api/login.json +16 -4
  7. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/data/api/search.json +4 -2
  8. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/data/api/song.json +2 -1
  9. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/data/api/songlist.json +3 -3
  10. qqmusic_api_python-0.1.8/qqmusic_api/data/api/user.json +171 -0
  11. qqmusic_api_python-0.1.8/qqmusic_api/data/api-schema.json +102 -0
  12. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/data/file_type.json +7 -3
  13. qqmusic_api_python-0.1.8/qqmusic_api/exceptions/__init__.py +9 -0
  14. qqmusic_api_python-0.1.8/qqmusic_api/exceptions/api_exception.py +60 -0
  15. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/login.py +75 -52
  16. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/mv.py +2 -2
  17. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/search.py +1 -1
  18. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/song.py +202 -158
  19. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/songlist.py +4 -2
  20. qqmusic_api_python-0.1.8/qqmusic_api/user.py +280 -0
  21. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/utils/credential.py +56 -46
  22. qqmusic_api_python-0.1.8/qqmusic_api/utils/network.py +310 -0
  23. qqmusic_api_python-0.1.8/qqmusic_api/utils/sync.py +27 -0
  24. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/utils/tripledes.py +46 -535
  25. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/utils/utils.py +9 -0
  26. qqmusic_api_python-0.1.8/tests/conftest.py +84 -0
  27. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/tests/test_album.py +1 -1
  28. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/tests/test_login.py +3 -3
  29. qqmusic_api_python-0.1.8/tests/test_lyric.py +19 -0
  30. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/tests/test_mv.py +1 -1
  31. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/tests/test_search.py +1 -1
  32. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/tests/test_singer.py +2 -4
  33. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/tests/test_song.py +1 -1
  34. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/tests/test_songlist.py +1 -1
  35. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/tests/test_top.py +1 -1
  36. qqmusic_api_python-0.1.8/tests/test_user.py +65 -0
  37. qqmusic_api_python-0.1.7/qqmusic_api/exceptions/ApiException.py +0 -12
  38. qqmusic_api_python-0.1.7/qqmusic_api/exceptions/CredentialNoMusicidException.py +0 -10
  39. qqmusic_api_python-0.1.7/qqmusic_api/exceptions/CredentialNoMusickeyException.py +0 -10
  40. qqmusic_api_python-0.1.7/qqmusic_api/exceptions/CredentialNoRefreshkeyException.py +0 -10
  41. qqmusic_api_python-0.1.7/qqmusic_api/exceptions/LoginException.py +0 -10
  42. qqmusic_api_python-0.1.7/qqmusic_api/exceptions/ResponseCodeException.py +0 -24
  43. qqmusic_api_python-0.1.7/qqmusic_api/exceptions/__init__.py +0 -15
  44. qqmusic_api_python-0.1.7/qqmusic_api/utils/network.py +0 -264
  45. qqmusic_api_python-0.1.7/qqmusic_api/utils/sync.py +0 -32
  46. qqmusic_api_python-0.1.7/tests/__init__.py +0 -3
  47. qqmusic_api_python-0.1.7/tests/conftest.py +0 -49
  48. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/LICENSE +0 -0
  49. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/data/api/album.json +0 -0
  50. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/data/api/lyric.json +0 -0
  51. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/data/api/mv.json +0 -0
  52. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/data/api/singer.json +0 -0
  53. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/data/api/top.json +0 -0
  54. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/data/search_type.json +0 -0
  55. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/lyric.py +0 -0
  56. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/singer.py +0 -0
  57. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/top.py +0 -0
  58. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/utils/__init__.py +0 -0
  59. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/qqmusic_api/utils/qimei.py +0 -0
  60. {qqmusic_api_python-0.1.7 → qqmusic_api_python-0.1.8}/tests/test_qimei.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: qqmusic-api-python
3
- Version: 0.1.7
3
+ Version: 0.1.8
4
4
  Summary: QQ音乐API封装库
5
5
  Keywords: music,api,qqmusic,tencentmusic
6
6
  Home-page: https://github.com/luren-dc/QQMusicApi
@@ -20,7 +20,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
20
  Project-URL: Homepage, https://github.com/luren-dc/QQMusicApi
21
21
  Project-URL: Repository, https://github.com/luren-dc/QQMusicApi
22
22
  Project-URL: Documentation, https://github.com/luren-dc/QQMusicApi
23
- Requires-Python: <4.0,>=3.9
23
+ Requires-Python: <3.13,>=3.9
24
24
  Requires-Dist: cryptography<42.0.0,>=41.0.2
25
25
  Requires-Dist: typing-extensions>=4.12.2
26
26
  Requires-Dist: httpx>=0.27.0
@@ -30,7 +30,7 @@ Description-Content-Type: text/markdown
30
30
  <h1> QQMusicApi </h1>
31
31
  <p> Python QQ音乐 API 封装库 </p>
32
32
  <a href="https://www.python.org">
33
- <img src="https://img.shields.io/badge/python-3.9+-blue" alt="Python">
33
+ <img src="https://img.shields.io/badge/python-3.9|3.10|3.11|3.12-blue" alt="Python">
34
34
  </a>
35
35
  <a href="https://github.com/astral-sh/ruff">
36
36
  <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
@@ -101,9 +101,15 @@ asyncio.run(main())
101
101
 
102
102
  ## 参考项目
103
103
 
104
- - [Rain120/qq-muisc-api](https://github.com/Rain120/qq-music-api)
105
- - [jsososo/QQMusicApi](https://github.com/jsososo/QQMusicApi)
106
- - [Nemo2011/bilibili-api](https://github.com/Nemo2011/bilibili-api/)
104
+ ### API
105
+ [![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=Rain120&repo=qq-music-api)](https://github.com/Rain120/qq-music-api)
106
+ [![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=jsososo&repo=QQMusicApi)](https://github.com/jsososo/QQMusicApi)
107
+
108
+ ### QRC 解密
109
+ [![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=chenmozhijin&repo=LDDC)](https://github.com/chenmozhijin/LDDC)
110
+
111
+ ### 项目架构
112
+ [![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=Nemo2011&repo=bilibili-api)](https://github.com/Nemo2011/bilibili-api)
107
113
 
108
114
  ## Licence
109
115
 
@@ -2,7 +2,7 @@
2
2
  <h1> QQMusicApi </h1>
3
3
  <p> Python QQ音乐 API 封装库 </p>
4
4
  <a href="https://www.python.org">
5
- <img src="https://img.shields.io/badge/python-3.9+-blue" alt="Python">
5
+ <img src="https://img.shields.io/badge/python-3.9|3.10|3.11|3.12-blue" alt="Python">
6
6
  </a>
7
7
  <a href="https://github.com/astral-sh/ruff">
8
8
  <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
@@ -73,9 +73,15 @@ asyncio.run(main())
73
73
 
74
74
  ## 参考项目
75
75
 
76
- - [Rain120/qq-muisc-api](https://github.com/Rain120/qq-music-api)
77
- - [jsososo/QQMusicApi](https://github.com/jsososo/QQMusicApi)
78
- - [Nemo2011/bilibili-api](https://github.com/Nemo2011/bilibili-api/)
76
+ ### API
77
+ [![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=Rain120&repo=qq-music-api)](https://github.com/Rain120/qq-music-api)
78
+ [![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=jsososo&repo=QQMusicApi)](https://github.com/jsososo/QQMusicApi)
79
+
80
+ ### QRC 解密
81
+ [![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=chenmozhijin&repo=LDDC)](https://github.com/chenmozhijin/LDDC)
82
+
83
+ ### 项目架构
84
+ [![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=Nemo2011&repo=bilibili-api)](https://github.com/Nemo2011/bilibili-api)
79
85
 
80
86
  ## Licence
81
87
 
@@ -15,7 +15,7 @@ dependencies = [
15
15
  "typing-extensions>=4.12.2",
16
16
  "httpx>=0.27.0",
17
17
  ]
18
- requires-python = "<4.0,>=3.9"
18
+ requires-python = "<3.13,>=3.9"
19
19
  readme = "README.md"
20
20
  maintainers = [
21
21
  { name = "Luren", email = "68656403+luren-dc@users.noreply.github.com" },
@@ -39,7 +39,7 @@ classifiers = [
39
39
  "Topic :: Software Development :: Libraries :: Python Modules",
40
40
  ]
41
41
  dynamic = []
42
- version = "0.1.7"
42
+ version = "0.1.8"
43
43
 
44
44
  [project.license]
45
45
  text = "MIT"
@@ -69,6 +69,8 @@ docs = [
69
69
  "mkdocs>=1.6.0",
70
70
  "markdown-callouts>=0.4.0",
71
71
  "griffe-inherited-docstrings>=1.0.0",
72
+ "docstring-inheritance>=2.2.1",
73
+ "griffe-modernized-annotations>=1.0.8",
72
74
  ]
73
75
  mypy = [
74
76
  "mypy>=1.11.0",
@@ -143,3 +145,4 @@ testpaths = [
143
145
  "tests",
144
146
  ]
145
147
  asyncio_mode = "auto"
148
+ asyncio_default_fixture_loop_scope = "session"
@@ -1,9 +1,9 @@
1
- from . import album, login, lyric, mv, search, singer, song, songlist, top
1
+ from . import album, login, lyric, mv, search, singer, song, songlist, top, user
2
2
  from .utils.credential import Credential
3
3
  from .utils.network import get_session, set_session
4
4
  from .utils.sync import sync
5
5
 
6
- __version__ = "0.1.7"
6
+ __version__ = "0.1.8"
7
7
 
8
8
  __all__ = [
9
9
  "album",
@@ -19,4 +19,5 @@ __all__ = [
19
19
  "songlist",
20
20
  "sync",
21
21
  "top",
22
+ "user",
22
23
  ]
@@ -33,8 +33,8 @@ class Album:
33
33
  """
34
34
  if mid is None and id is None:
35
35
  raise ValueError("mid or id must be provided")
36
- self.mid = mid
37
- self.id = id
36
+ self.mid = mid or ""
37
+ self.id = id or 0
38
38
  self._info: Optional[dict] = None
39
39
 
40
40
  async def get_mid(self) -> str:
@@ -43,7 +43,9 @@ class Album:
43
43
  Returns:
44
44
  专辑 mid
45
45
  """
46
- return (await self.get_detail())["basicInfo"]["albumMid"]
46
+ if not self.mid:
47
+ self.mid = (await self.get_detail())["basicInfo"]["albumMid"]
48
+ return self.mid
47
49
 
48
50
  async def get_id(self) -> int:
49
51
  """获取专辑 id
@@ -51,7 +53,9 @@ class Album:
51
53
  Returns:
52
54
  专辑 id
53
55
  """
54
- return (await self.get_detail())["basicInfo"]["albumID"]
56
+ if not self.id:
57
+ self.id = (await self.get_detail())["basicInfo"]["albumID"]
58
+ return self.id
55
59
 
56
60
  async def get_detail(self) -> dict:
57
61
  """获取专辑详细信息
@@ -6,7 +6,8 @@
6
6
  "code": "str 鉴权码",
7
7
  "musicid": "int",
8
8
  "musickey": "str",
9
- "refresh_key": "str"
9
+ "refresh_key": "str",
10
+ "refresh_token": "str"
10
11
  },
11
12
  "extra_common": {
12
13
  "tmeLoginType": "str 2"
@@ -19,9 +20,10 @@
19
20
  "params": {
20
21
  "strAppid": "wx48db31d50e334801",
21
22
  "code": "str 鉴权码",
22
- "str_musicid": "str",
23
+ "musicid": "int",
23
24
  "musickey": "str",
24
25
  "refresh_key": "str",
26
+ "refresh_token": "str",
25
27
  "loginMode": "int 2"
26
28
  },
27
29
  "extra_common": {
@@ -32,6 +34,7 @@
32
34
  "send_authcode": {
33
35
  "module": "music.login.LoginServer",
34
36
  "method": "SendPhoneAuthCode",
37
+ "ignore_code": true,
35
38
  "params": {
36
39
  "tmeAppid": "qqmusic",
37
40
  "phoneNo": "str 手机号",
@@ -45,14 +48,23 @@
45
48
  "phone_login": {
46
49
  "module": "music.login.LoginServer",
47
50
  "method": "Login",
51
+ "ignore_code": true,
48
52
  "params": {
49
53
  "code": "str 验证码",
50
54
  "phoneNo": "str 手机号",
51
55
  "loginMode": "int 1"
52
56
  },
53
57
  "extra_common": {
54
- "tmeLoginMethod": "str 3"
58
+ "tmeLoginMethod": "str 3",
59
+ "tmeLoginType": "str 0"
55
60
  },
56
- "comment": "发送验证码"
61
+ "comment": "手机验证码鉴权"
62
+ },
63
+ "check_expired": {
64
+ "module": "music.UserInfo.userInfoServer",
65
+ "method": "GetLoginUserInfo",
66
+ "verify": true,
67
+ "params": {},
68
+ "comment": "获取登录用户的信息,用于检测凭证是否失效"
57
69
  }
58
70
  }
@@ -8,7 +8,7 @@
8
8
  "comment": "获取热搜词"
9
9
  },
10
10
  "complete": {
11
- "module": "tencent_music_soso_smartbox_cgi.SmartBoxCgi",
11
+ "module": "music.smartboxCgi.SmartBoxCgi",
12
12
  "method": "GetSmartBoxResult",
13
13
  "params": {
14
14
  "search_id": "int 随机生成",
@@ -21,10 +21,11 @@
21
21
  "quick_search": {
22
22
  "url": "https://c.y.qq.com/splcloud/fcgi-bin/smartbox_new.fcg",
23
23
  "method": "GET",
24
+ "platform": "web",
24
25
  "params": {
25
26
  "key": "str 搜索词"
26
27
  },
27
- "comment": "桌面端快速搜索"
28
+ "comment": "快速搜索"
28
29
  },
29
30
  "general_search": {
30
31
  "module": "music.adaptor.SearchAdaptor",
@@ -43,6 +44,7 @@
43
44
  "desktop_search_by_type": {
44
45
  "module": "music.search.SearchCgiService",
45
46
  "method": "DoSearchForQQMusicDesktop",
47
+ "platform": "desktop",
46
48
  "params": {
47
49
  "search_id": "int 随机生成",
48
50
  "search_type": "int 搜索类型",
@@ -68,7 +68,8 @@
68
68
  "module": "music.mir.SheetMusicSvr",
69
69
  "method": "GetMoreSheetMusic",
70
70
  "params": {
71
- "songmid": "str 歌曲 mid"
71
+ "songmid": "str 歌曲 mid",
72
+ "scoreType": "int -1"
72
73
  },
73
74
  "comment": "获取相关曲谱"
74
75
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "detail": {
3
- "module": "srf_diss_info.DissInfoServer",
3
+ "module": "music.srfDissInfo.DissInfo",
4
4
  "method": "CgiGetDiss",
5
5
  "params": {
6
6
  "disstid": "int 歌单ID",
@@ -9,9 +9,9 @@
9
9
  "onlysonglist": "int 是否只返回歌曲",
10
10
  "song_begin": "int 开始位置",
11
11
  "song_num": "int 返回数量",
12
- "userinfo": "int 是否返回以后信息",
12
+ "userinfo": "int 是否返回用户信息",
13
13
  "orderlist": "int 是否排序歌单",
14
- "caller": "str musicid"
14
+ "enc_host_uin": "str encrypt_uin"
15
15
  }
16
16
  }
17
17
  }
@@ -0,0 +1,171 @@
1
+ {
2
+ "profile": {
3
+ "url": "https://c6.y.qq.com/rsc/fcgi-bin/fcg_get_profile_homepage.fcg",
4
+ "method": "GET",
5
+ "platform": "web",
6
+ "headers": {
7
+ "referer": "https://y.qq.com/"
8
+ },
9
+ "params": {
10
+ "ct": "int 20",
11
+ "cv": "int 4747474",
12
+ "cid": "int 205360838",
13
+ "userid": "str musicid or euin"
14
+ },
15
+ "comment": "获取用户主页,根据 cookie 值不同,内容有差异"
16
+ },
17
+ "vip_info": {
18
+ "module": "VipLogin.VipLoginInter",
19
+ "method": "vip_login_base",
20
+ "verify": true,
21
+ "params": {},
22
+ "comment": "获取当前登录账号的 vip 信息"
23
+ },
24
+ "homepage": {
25
+ "module": "music.UnifiedHomepage.UnifiedHomepageSrv",
26
+ "method": "GetHomepageHeader",
27
+ "params": {
28
+ "uin": "str musicid or euin",
29
+ "IsQueryTabDetail": "int 1"
30
+ },
31
+ "comment": "获取用户主页信息(包含用户信息,音乐基因,乐库,用户歌单等信息),根据 cookie 值不同,内容有差异"
32
+ },
33
+ "friend": {
34
+ "module": "music.homepage.Friendship",
35
+ "method": "GetFriendList",
36
+ "verify": true,
37
+ "params": {
38
+ "Page": "int 页数",
39
+ "PageSize": "int 每页数量"
40
+ },
41
+ "comment": "获取好友列表"
42
+ },
43
+ "songlist_by_euin": {
44
+ "url": "https://c6.y.qq.com/rsc/fcgi-bin/fcg_user_created_diss",
45
+ "method": "GET",
46
+ "platform": "web",
47
+ "headers": {
48
+ "referer": "https://y.qq.com/"
49
+ },
50
+ "params": {
51
+ "hostuin": "str encrypt_uin",
52
+ "sin": "int 页数",
53
+ "size": "int 每页返回数量"
54
+ },
55
+ "comment": "通过 encrypt_uin 获取用户歌单列表"
56
+ },
57
+ "songlist_by_uin": {
58
+ "module": "music.musicasset.PlaylistBaseRead",
59
+ "method": "GetPlaylistByUin",
60
+ "platform": "desktop",
61
+ "params": {
62
+ "uin": "str uin"
63
+ },
64
+ "comment": "通过 uin 获取用户歌单列表"
65
+ },
66
+ "follow_singer": {
67
+ "module": "music.concern.RelationList",
68
+ "method": "GetFollowSingerList",
69
+ "verify": true,
70
+ "params": {
71
+ "From": "int 起始序号",
72
+ "Size": "int 返回数量",
73
+ "HostUin": "str encrypt_uin"
74
+ },
75
+ "comment": "获取关注歌手列表"
76
+ },
77
+ "follow_user": {
78
+ "module": "music.concern.RelationList",
79
+ "method": "GetFollowUserList",
80
+ "verify": true,
81
+ "params": {
82
+ "From": "int 起始序号",
83
+ "Size": "int 返回数量",
84
+ "HostUin": "str encrypt_uin"
85
+ },
86
+ "comment": "获取关注用户列表"
87
+ },
88
+ "fans": {
89
+ "module": "music.concern.RelationList",
90
+ "method": "GetFansList",
91
+ "verify": true,
92
+ "params": {
93
+ "From": "int 起始序号",
94
+ "Size": "int 返回数量",
95
+ "HostUin": "str encrypt_uin"
96
+ },
97
+ "comment": "获取粉丝列表"
98
+ },
99
+ "fav_songlist_self": {
100
+ "module": "music.mobileAsset.GetFav",
101
+ "method": "CgiGetOrderDiss",
102
+ "verify": true,
103
+ "params": {},
104
+ "comment": "获取当前登录用户收藏歌单"
105
+ },
106
+ "fav_album_self": {
107
+ "module": "music.mobileAsset.GetFav",
108
+ "method": "CgiGetOrderAlbum",
109
+ "verify": true,
110
+ "params": {},
111
+ "comment": "获取当前登录用户收藏专辑"
112
+ },
113
+ "fav_mv_self": {
114
+ "module": "music.mobileAsset.GetFav",
115
+ "method": "CgiGetOrderMV",
116
+ "verify": true,
117
+ "params": {},
118
+ "comment": "获取当前登录用户收藏MV"
119
+ },
120
+ "fav_songlist_by_euin": {
121
+ "module": "music.musicasset.PlaylistFavRead",
122
+ "method": "CgiGetPlaylistFavInfo",
123
+ "params": {
124
+ "uin": "str encrypt_uin",
125
+ "offset": "int 偏移量",
126
+ "size": "int 返回数量"
127
+ },
128
+ "comment": "通过 encrypt_uin 获取收藏歌单"
129
+ },
130
+ "fav_album_by_euin": {
131
+ "module": "music.musicasset.AlbumFavRead",
132
+ "method": "CgiGetAlbumFavInfo",
133
+ "params": {
134
+ "euin": "str encrypt_uin",
135
+ "offset": "int 偏移量",
136
+ "size": "int 返回数量"
137
+ },
138
+ "comment": "通过 encrypt_uin 获取收藏专辑"
139
+ },
140
+ "fav_mv": {
141
+ "module": "music.musicasset.MVFavRead",
142
+ "method": "getMyFavMV",
143
+ "verify": true,
144
+ "params": {
145
+ "uin": "str musicid or euin",
146
+ "support": "int 1",
147
+ "req_icon_type": "int 1"
148
+ },
149
+ "comment": "获取收藏 MV"
150
+ },
151
+ "fav_mv_by_euin": {
152
+ "module": "music.musicasset.MVFavRead",
153
+ "method": "getMyFavMV_v2",
154
+ "platform": "desktop",
155
+ "verify": true,
156
+ "params": {
157
+ "encuin": "str encrypt_uin",
158
+ "num": "int 返回数量",
159
+ "pagesize": "int 返回页数"
160
+ },
161
+ "comment": "通过 encrypt_uin 获取收藏 MV"
162
+ },
163
+ "music_gene": {
164
+ "module": "music.recommend.UserProfileSettingSvr",
165
+ "method": "GetProfileReport",
166
+ "params": {
167
+ "VisitAccount": "str encrypt_uin"
168
+ },
169
+ "comment": "获取音乐基因数据"
170
+ }
171
+ }
@@ -0,0 +1,102 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft-07/schema",
3
+ "type": "object",
4
+ "properties": {
5
+ "$schema": {
6
+ "type": "string",
7
+ "format": "uri-reference"
8
+ }
9
+ },
10
+ "patternProperties": {
11
+ ".*": {
12
+ "type": "object",
13
+ "properties": {
14
+ "url": {
15
+ "type": "string",
16
+ "description": "请求地址"
17
+ },
18
+ "method": {
19
+ "type": "string",
20
+ "description": "请求方法"
21
+ },
22
+ "headers": {
23
+ "type": "object",
24
+ "description": "请求头"
25
+ },
26
+ "module": {
27
+ "type": "string",
28
+ "description": "QQ音乐请求模块,搭配 `method` 使用"
29
+ },
30
+ "data": {
31
+ "type": "object",
32
+ "description": "请求数据"
33
+ },
34
+ "params": {
35
+ "type": "object",
36
+ "description": "请求参数"
37
+ },
38
+ "json_body": {
39
+ "type": "boolean",
40
+ "description": "是否使用 json 作为载荷"
41
+ },
42
+ "verify": {
43
+ "type": "boolean",
44
+ "description": "是否验证账号凭证"
45
+ },
46
+ "platform": {
47
+ "type": "string",
48
+ "description": "API 来源",
49
+ "enum": [
50
+ "mobile",
51
+ "desktop",
52
+ "web"
53
+ ]
54
+ },
55
+ "ignore_code": {
56
+ "type": "boolean",
57
+ "description": "是否忽略返回值 code 检验直接返回"
58
+ },
59
+ "extra_common": {
60
+ "type": "object",
61
+ "description": "请求QQ音乐的额外公共参数"
62
+ },
63
+ "comment": {
64
+ "type": "string",
65
+ "description": "接口描述"
66
+ }
67
+ },
68
+ "allOf": [
69
+ {
70
+ "if": {
71
+ "properties": {
72
+ "module": {
73
+ "type": "string"
74
+ }
75
+ },
76
+ "required": [
77
+ "module"
78
+ ]
79
+ },
80
+ "then": {
81
+ "not": {
82
+ "required": [
83
+ "url",
84
+ "data"
85
+ ]
86
+ },
87
+ "required": [
88
+ "method",
89
+ "params"
90
+ ]
91
+ },
92
+ "else": {
93
+ "required": [
94
+ "url",
95
+ "method"
96
+ ]
97
+ }
98
+ }
99
+ ]
100
+ }
101
+ }
102
+ }
@@ -1,13 +1,13 @@
1
1
  {
2
- "new_0": {
2
+ "master": {
3
3
  "s": "AI00",
4
4
  "e": ".flac"
5
5
  },
6
- "new_1": {
6
+ "atmos_2": {
7
7
  "s": "Q000",
8
8
  "e": ".flac"
9
9
  },
10
- "new_2": {
10
+ "atmos_51": {
11
11
  "s": "Q001",
12
12
  "e": ".flac"
13
13
  },
@@ -15,6 +15,10 @@
15
15
  "s": "F000",
16
16
  "e": ".flac"
17
17
  },
18
+ "ogg_640": {
19
+ "s": "O801",
20
+ "e": ".ogg"
21
+ },
18
22
  "ogg_320": {
19
23
  "s": "O800",
20
24
  "e": ".ogg"
@@ -0,0 +1,9 @@
1
+ from .api_exception import *
2
+
3
+ __all__ = [
4
+ "ApiException",
5
+ "CredentialInvalidError",
6
+ "CredentialExpiredError",
7
+ "LoginError",
8
+ "ResponseCodeError",
9
+ ]
@@ -0,0 +1,60 @@
1
+ """API Exception"""
2
+
3
+
4
+ class ApiException(Exception):
5
+ """API Exception 基类"""
6
+
7
+ def __init__(self, message: str = "出现了错误,但未说明原因") -> None:
8
+ super().__init__(message)
9
+ self.message = message
10
+
11
+ def __str__(self) -> str:
12
+ return self.message
13
+
14
+
15
+ class ResponseCodeError(ApiException):
16
+ """API 返回响应的 code 不符合预期"""
17
+
18
+ def __init__(
19
+ self,
20
+ code: int,
21
+ data: dict,
22
+ raw: dict,
23
+ message: str = "API 返回的响应 code 不符合预期",
24
+ ) -> None:
25
+ self.code = code
26
+ self.data = data
27
+ self.raw = raw
28
+ self.message = message
29
+
30
+ def __str__(self) -> str:
31
+ return f"[{self.code}] {self.message}"
32
+
33
+
34
+ class CredentialExpiredError(ResponseCodeError):
35
+ """Credential 过期"""
36
+
37
+ def __init__(
38
+ self,
39
+ data: dict,
40
+ raw: dict,
41
+ message: str = "凭证已过期",
42
+ ) -> None:
43
+ super().__init__(1000, data, raw, message)
44
+
45
+ def __str__(self) -> str:
46
+ return self.message
47
+
48
+
49
+ class CredentialInvalidError(ApiException):
50
+ """Credential 无效"""
51
+
52
+ def __init__(self, message: str = "凭证无效") -> None:
53
+ super().__init__(message)
54
+
55
+
56
+ class LoginError(ApiException):
57
+ """登录失败"""
58
+
59
+ def __init__(self, message: str = "登录失败") -> None:
60
+ super().__init__(message)