qqmusic-api-python 0.1.0__py3-none-any.whl
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.
- qqmusic_api/__init__.py +4 -0
- qqmusic_api/api/album.py +40 -0
- qqmusic_api/api/login.py +437 -0
- qqmusic_api/api/mv.py +115 -0
- qqmusic_api/api/search.py +168 -0
- qqmusic_api/api/song.py +389 -0
- qqmusic_api/api/songlist.py +81 -0
- qqmusic_api/api/top.py +98 -0
- qqmusic_api/data/api/album.json +20 -0
- qqmusic_api/data/api/login.json +69 -0
- qqmusic_api/data/api/mv.json +26 -0
- qqmusic_api/data/api/search.json +73 -0
- qqmusic_api/data/api/singer.json +1 -0
- qqmusic_api/data/api/song.json +105 -0
- qqmusic_api/data/api/songlist.json +17 -0
- qqmusic_api/data/api/top.json +20 -0
- qqmusic_api/data/file_type.json +50 -0
- qqmusic_api/data/search_type.json +11 -0
- qqmusic_api/exceptions.py +121 -0
- qqmusic_api/settings.py +22 -0
- qqmusic_api/utils/__init__.py +0 -0
- qqmusic_api/utils/common.py +140 -0
- qqmusic_api/utils/credential.py +92 -0
- qqmusic_api/utils/network.py +249 -0
- qqmusic_api/utils/qimei.py +267 -0
- qqmusic_api_python-0.1.0.dist-info/LICENSE +21 -0
- qqmusic_api_python-0.1.0.dist-info/METADATA +99 -0
- qqmusic_api_python-0.1.0.dist-info/RECORD +29 -0
- qqmusic_api_python-0.1.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import datetime
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import random
|
|
6
|
+
import time
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
import requests
|
|
11
|
+
from cryptography.hazmat.primitives import serialization
|
|
12
|
+
from cryptography.hazmat.primitives.asymmetric import padding
|
|
13
|
+
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
|
14
|
+
|
|
15
|
+
from .common import calc_md5, get_cache_file, random_string
|
|
16
|
+
|
|
17
|
+
PUBLIC_KEY = """-----BEGIN PUBLIC KEY-----
|
|
18
|
+
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEIxgwoutfwoJxcGQeedgP7FG9qaIuS0qzfR8gWkrkTZKM2iWHn2ajQpBRZjMSoSf6+KJGvar2ORhBfpDXyVtZCKpqLQ+FLkpncClKVIrBwv6PHyUvuCb0rIarmgDnzkfQAqVufEtR64iazGDKatvJ9y6B9NMbHddGSAUmRTCrHQIDAQAB
|
|
19
|
+
-----END PUBLIC KEY-----"""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class QImeiResult:
|
|
24
|
+
"""获取QImei返回结果"""
|
|
25
|
+
|
|
26
|
+
q16: str # Qimei16
|
|
27
|
+
q36: str # Qimei36
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
device_payload_path = get_cache_file("device.json")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def get_device_payload(version):
|
|
34
|
+
if os.path.exists(device_payload_path):
|
|
35
|
+
with open(device_payload_path, encoding="utf8") as f:
|
|
36
|
+
data = json.load(f)
|
|
37
|
+
else:
|
|
38
|
+
with open(device_payload_path, mode="w", encoding="utf8") as f:
|
|
39
|
+
data = Qimei.gen_random_payload(version)
|
|
40
|
+
f.write(json.dumps(data))
|
|
41
|
+
return data
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def rsa_encrypt(content: bytes) -> bytes:
|
|
45
|
+
"""
|
|
46
|
+
使用RSA算法对数据进行加密
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
data: 待加密的数据
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
加密后的数据
|
|
53
|
+
"""
|
|
54
|
+
key = serialization.load_pem_public_key(PUBLIC_KEY.encode())
|
|
55
|
+
return key.encrypt(content, padding.PKCS1v15())
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class AES:
|
|
59
|
+
block_size = 16
|
|
60
|
+
|
|
61
|
+
def __init__(self, key: bytes):
|
|
62
|
+
self._cipher = Cipher(algorithms.AES(key), modes.CBC(key))
|
|
63
|
+
|
|
64
|
+
@staticmethod
|
|
65
|
+
def _pad(v: bytes) -> bytes:
|
|
66
|
+
padding_size = AES.block_size - len(v) % AES.block_size
|
|
67
|
+
return v + (padding_size * chr(padding_size)).encode()
|
|
68
|
+
|
|
69
|
+
@staticmethod
|
|
70
|
+
def _unpad(v: bytes) -> bytes:
|
|
71
|
+
return v[: -v[-1]]
|
|
72
|
+
|
|
73
|
+
def encrypt(self, content: bytes) -> bytes:
|
|
74
|
+
enc = self._cipher.encryptor()
|
|
75
|
+
return enc.update(self._pad(content)) + enc.finalize()
|
|
76
|
+
|
|
77
|
+
def decrypt(self, content: bytes) -> bytes:
|
|
78
|
+
dec = self._cipher.decryptor()
|
|
79
|
+
return self._unpad(dec.update(content) + dec.finalize())
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class Qimei:
|
|
83
|
+
APP_KEY = "0AND0HD6FE4HY80F"
|
|
84
|
+
SECRET = "ZdJqM15EeO2zWc08"
|
|
85
|
+
|
|
86
|
+
@staticmethod
|
|
87
|
+
def gen_query(device: dict) -> tuple[dict[str, Any], str]:
|
|
88
|
+
"""
|
|
89
|
+
生成查询参数和时间戳
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
device: 设备信息字典
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
查询参数和时间戳的元组
|
|
96
|
+
"""
|
|
97
|
+
crypt_key = random_string(16, "abcdef1234567890")
|
|
98
|
+
nonce = random_string(16, "abcdef1234567890")
|
|
99
|
+
ts = int(time.time() * 1000)
|
|
100
|
+
key = base64.b64encode(rsa_encrypt(crypt_key.encode())).decode()
|
|
101
|
+
aes = AES(crypt_key.encode())
|
|
102
|
+
params = base64.b64encode(aes.encrypt(json.dumps(device).encode())).decode()
|
|
103
|
+
extra = '{"appKey":"' + Qimei.APP_KEY + '"}'
|
|
104
|
+
sign = calc_md5(
|
|
105
|
+
key,
|
|
106
|
+
params,
|
|
107
|
+
str(ts),
|
|
108
|
+
nonce,
|
|
109
|
+
Qimei.SECRET,
|
|
110
|
+
extra,
|
|
111
|
+
)
|
|
112
|
+
data = {
|
|
113
|
+
"app": 0,
|
|
114
|
+
"os": 1,
|
|
115
|
+
"qimeiParams": {
|
|
116
|
+
"key": key,
|
|
117
|
+
"params": params,
|
|
118
|
+
"time": str(ts),
|
|
119
|
+
"nonce": nonce,
|
|
120
|
+
"sign": sign,
|
|
121
|
+
"extra": extra,
|
|
122
|
+
},
|
|
123
|
+
}
|
|
124
|
+
return data, str(int(ts / 1000))
|
|
125
|
+
|
|
126
|
+
@staticmethod
|
|
127
|
+
def gen_random_payload(version) -> dict:
|
|
128
|
+
"""
|
|
129
|
+
生成随机的payload字典
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
随机的payload字典
|
|
133
|
+
"""
|
|
134
|
+
beacon_id = ""
|
|
135
|
+
time_month = datetime.datetime.now().strftime("%Y-%m-") + "01"
|
|
136
|
+
rand1 = random.randint(100000, 999999)
|
|
137
|
+
rand2 = random.randint(100000000, 999999999)
|
|
138
|
+
|
|
139
|
+
for i in range(1, 41):
|
|
140
|
+
if i in [1, 2, 13, 14, 17, 18, 21, 22, 25, 26, 29, 30, 33, 34, 37, 38]:
|
|
141
|
+
beacon_id += f"k{i}:{time_month}{rand1}.{rand2}"
|
|
142
|
+
elif i == 3:
|
|
143
|
+
beacon_id += "k3:0000000000000000"
|
|
144
|
+
elif i == 4:
|
|
145
|
+
beacon_id += f"k4:{''.join(random.choices('123456789abcdef', k=16))}"
|
|
146
|
+
else:
|
|
147
|
+
beacon_id += f"k{i}:{random.randint(0, 9999)}"
|
|
148
|
+
beacon_id += ";"
|
|
149
|
+
brand = random.choice(("VIVO", "Xiaomi", "OPPO", "HUAWEI", "Redmi", "Realme"))
|
|
150
|
+
|
|
151
|
+
fixed_rand_seconds = random.randint(0, 14400)
|
|
152
|
+
current_time = datetime.datetime.now()
|
|
153
|
+
time_result = current_time - datetime.timedelta(seconds=fixed_rand_seconds)
|
|
154
|
+
formatted_time = time_result.strftime("%Y-%m-%d %H:%M:%S")
|
|
155
|
+
reserved = {
|
|
156
|
+
"harmony": "0",
|
|
157
|
+
"clone": "0",
|
|
158
|
+
"containe": "",
|
|
159
|
+
"oz": "UhYmelwouA+V2nPWbOvLTgN2/m8jwGB+yUB5v9tysQg=",
|
|
160
|
+
"oo": "Xecjt+9S1+f8Pz2VLSxgpw==",
|
|
161
|
+
"kelong": "0",
|
|
162
|
+
"uptimes": formatted_time,
|
|
163
|
+
"multiUser": "0",
|
|
164
|
+
"bod": brand,
|
|
165
|
+
"brd": brand,
|
|
166
|
+
"dv": "PCRT00",
|
|
167
|
+
"firstLevel": "",
|
|
168
|
+
"manufact": brand,
|
|
169
|
+
"name": "PCRT00",
|
|
170
|
+
"host": "se.infra",
|
|
171
|
+
"kernel": "Linux localhost 4.14.253-android+ #754 SMP Wed Nov 9 17:04:03 CST 2022 armv8",
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
"androidId": "BRAND.141613.779",
|
|
176
|
+
"platformId": 1,
|
|
177
|
+
"appKey": Qimei.APP_KEY,
|
|
178
|
+
"appVersion": version,
|
|
179
|
+
"beaconIdSrc": beacon_id,
|
|
180
|
+
"brand": brand,
|
|
181
|
+
"channelId": "10003505",
|
|
182
|
+
"cid": "",
|
|
183
|
+
"imei": Qimei.gen_random_imei(),
|
|
184
|
+
"imsi": "",
|
|
185
|
+
"mac": "",
|
|
186
|
+
"model": "",
|
|
187
|
+
"networkType": "unknown",
|
|
188
|
+
"oaid": "",
|
|
189
|
+
"osVersion": "Android 13.0,level 33",
|
|
190
|
+
"qimei": "",
|
|
191
|
+
"qimei36": "",
|
|
192
|
+
"sdkVersion": "1.2.13.6",
|
|
193
|
+
"targetSdkVersion": "33",
|
|
194
|
+
"audit": "",
|
|
195
|
+
"userId": "{}",
|
|
196
|
+
"packageId": "com.tencent.qqmusic",
|
|
197
|
+
"deviceType": "Phone",
|
|
198
|
+
"sdkName": "",
|
|
199
|
+
"reserved": json.dumps(reserved, separators=(",", ":"), ensure_ascii=False),
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
@staticmethod
|
|
203
|
+
def gen_random_imei() -> str:
|
|
204
|
+
"""
|
|
205
|
+
生成随机的IMEI号码
|
|
206
|
+
|
|
207
|
+
Returns:
|
|
208
|
+
随机的IMEI号码
|
|
209
|
+
"""
|
|
210
|
+
tac = random.randint(100000, 999999)
|
|
211
|
+
snr = random.randint(100000, 999999)
|
|
212
|
+
imei_without_checksum = f"{tac}{snr}"
|
|
213
|
+
checksum = Qimei.calculate_luhn_checksum(imei_without_checksum)
|
|
214
|
+
return f"{imei_without_checksum}{checksum}"
|
|
215
|
+
|
|
216
|
+
@staticmethod
|
|
217
|
+
def calculate_luhn_checksum(number_str: str) -> int:
|
|
218
|
+
"""
|
|
219
|
+
计算Luhn校验和
|
|
220
|
+
|
|
221
|
+
Args:
|
|
222
|
+
number_str: 待计算的数字字符串
|
|
223
|
+
Returns:
|
|
224
|
+
Luhn校验和
|
|
225
|
+
"""
|
|
226
|
+
|
|
227
|
+
def digits_of(n: int) -> list[int]:
|
|
228
|
+
return [int(digit) for digit in str(n)]
|
|
229
|
+
|
|
230
|
+
digits = digits_of(int(number_str))
|
|
231
|
+
odd_digits_sum = sum(digits[-1::-2])
|
|
232
|
+
even_digits_sum = sum([sum(digits_of(2 * digit)) for digit in digits[-2::-2]])
|
|
233
|
+
total_sum = odd_digits_sum + even_digits_sum
|
|
234
|
+
return (10 - total_sum % 10) % 10
|
|
235
|
+
|
|
236
|
+
@staticmethod
|
|
237
|
+
def get(version: str) -> QImeiResult:
|
|
238
|
+
"""
|
|
239
|
+
获取 QImei(同步)
|
|
240
|
+
|
|
241
|
+
Returns:
|
|
242
|
+
随机QImei
|
|
243
|
+
"""
|
|
244
|
+
data, ts = Qimei.gen_query(get_device_payload(version))
|
|
245
|
+
sign = calc_md5("qimei_qq_androidpzAuCmaFAaFaHrdakPjLIEqKrGnSOOvH", ts)
|
|
246
|
+
try:
|
|
247
|
+
res = requests.post(
|
|
248
|
+
"https://api.tencentmusic.com/tme/trpc/proxy",
|
|
249
|
+
headers={
|
|
250
|
+
"Host": "api.tencentmusic.com",
|
|
251
|
+
"method": "GetQimei",
|
|
252
|
+
"service": "trpc.tme_datasvr.qimeiproxy.QimeiProxy",
|
|
253
|
+
"appid": "qimei_qq_android",
|
|
254
|
+
"sign": sign,
|
|
255
|
+
"user-agent": "QQMusic",
|
|
256
|
+
"timestamp": ts,
|
|
257
|
+
},
|
|
258
|
+
json=data,
|
|
259
|
+
)
|
|
260
|
+
except Exception:
|
|
261
|
+
return QImeiResult("", "")
|
|
262
|
+
qimei_data = str(res.json()["data"])
|
|
263
|
+
qimei = json.loads(qimei_data)
|
|
264
|
+
if qimei["code"] == 0:
|
|
265
|
+
return QImeiResult(qimei["data"]["q16"], qimei["data"]["q36"])
|
|
266
|
+
else:
|
|
267
|
+
return QImeiResult("", "")
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Luren
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: qqmusic-api-python
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: QQ音乐API封装库
|
|
5
|
+
Home-page: https://github.com/luren-dc/QQMusicApi
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: music,api,qqmusic,tencentmusic
|
|
8
|
+
Author: Luren
|
|
9
|
+
Author-email: dluren.c@gmail.com
|
|
10
|
+
Maintainer: Luren
|
|
11
|
+
Maintainer-email: dluren.c@gmail.com
|
|
12
|
+
Requires-Python: >=3.9,<4.0
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Framework :: Pytest
|
|
15
|
+
Classifier: Framework :: aiohttp
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Natural Language :: Chinese (Simplified)
|
|
18
|
+
Classifier: Programming Language :: Python
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
25
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
26
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
|
+
Requires-Dist: aiohttp (==3.9.5)
|
|
28
|
+
Requires-Dist: cryptography (==41.0.2)
|
|
29
|
+
Requires-Dist: requests (==2.31.0)
|
|
30
|
+
Project-URL: Documentation, https://github.com/luren-dc/QQMusicApi
|
|
31
|
+
Project-URL: Repository, https://github.com/luren-dc/QQMusicApi
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
<div align="center">
|
|
35
|
+
<h1> QQMusicApi </h1>
|
|
36
|
+
<p> Python QQ音乐 API 封装库 </p>
|
|
37
|
+
|
|
38
|
+

|
|
39
|
+
[](https://github.com/astral-sh/ruff)
|
|
40
|
+

|
|
41
|
+
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
> [!WARNING]
|
|
47
|
+
> 本仓库的所有内容仅供学习和参考之用,禁止用于商业用途。
|
|
48
|
+
|
|
49
|
+
## 介绍
|
|
50
|
+
|
|
51
|
+
使用 Python 编写的用于调用 [QQ音乐](https://y.qq.com/) 各种 API 的库.
|
|
52
|
+
|
|
53
|
+
## 依赖
|
|
54
|
+
|
|
55
|
+
本项目基于:
|
|
56
|
+
|
|
57
|
+
- [AIOHTTP](https://docs.aiohttp.org/)
|
|
58
|
+
- [Requests](https://requests.readthedocs.io/)
|
|
59
|
+
- [Cryptography](https://cryptography.io/)
|
|
60
|
+
|
|
61
|
+
## 快速上手
|
|
62
|
+
|
|
63
|
+
### 安装
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
$ pip3 install qqmusic-api-python
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 使用
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
import asyncio
|
|
73
|
+
|
|
74
|
+
from qqmusic_api import search
|
|
75
|
+
|
|
76
|
+
async def main():
|
|
77
|
+
# 搜索歌曲
|
|
78
|
+
result = await search.search_by_type(keyword="周杰伦", num=20)
|
|
79
|
+
# 打印结果
|
|
80
|
+
print(result)
|
|
81
|
+
|
|
82
|
+
if __name__ == "__main__":
|
|
83
|
+
asyncio.run(main())
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## TODO
|
|
87
|
+
|
|
88
|
+
- [ ] 歌手 API
|
|
89
|
+
|
|
90
|
+
## 参考项目
|
|
91
|
+
|
|
92
|
+
- [Rain120/qq-muisc-api](https://github.com/Rain120/qq-muisc-api)
|
|
93
|
+
- [jsososo/QQMusicApi](https://github.com/jsososo/QQMusicApi)
|
|
94
|
+
- [Nemo2011/bilibili-api](https://github.com/Nemo2011/bilibili-api/)
|
|
95
|
+
|
|
96
|
+
## Licence
|
|
97
|
+
|
|
98
|
+
**[MIT License](https://github.com/luren-dc/QQMusicApi/blob/master/LICENSE)**
|
|
99
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
qqmusic_api/__init__.py,sha256=KCIV6V_EHW-Pfd0ii3hnVcNamfQ2x-S8LnOE57ZnLM0,191
|
|
2
|
+
qqmusic_api/api/album.py,sha256=VPVhL1iSSASpj6j2iyiIre6kZXmxJWm41ugMxpC1B8w,874
|
|
3
|
+
qqmusic_api/api/login.py,sha256=v4X199hFc8-TZghq3kwi8P314EjZ2VG39nhsKHhOWnc,13986
|
|
4
|
+
qqmusic_api/api/mv.py,sha256=Qz8L9eTJQoenfNcVZtKRzUpJuyM68il70KO3FhZhvuI,2817
|
|
5
|
+
qqmusic_api/api/search.py,sha256=6TLPOv47caAGNFzrgZTBY_0nrjz1ap7QpKH5-6PyUWc,4337
|
|
6
|
+
qqmusic_api/api/song.py,sha256=gOK74bnk6izaeBZKEe0hGSi40Rmv_ZF9qm-2PzI_aH8,10549
|
|
7
|
+
qqmusic_api/api/songlist.py,sha256=S-ajFTdvzFLldUx_c7JfFDm-OETirszpbbVK9S2eej8,1897
|
|
8
|
+
qqmusic_api/api/top.py,sha256=osXDg-GkiWjZ5ePnmz-I6PD6UFUpO9jeUKO0tBkm-tM,2822
|
|
9
|
+
qqmusic_api/data/api/album.json,sha256=Kir-40oBAqt6_lXS9p2StEwgXKzZpgbsZT_zXKViaiU,539
|
|
10
|
+
qqmusic_api/data/api/login.json,sha256=UB3ORUxYcSDd3FCR83HjiyGN8MZIaB2XCHBpBflNS2k,1840
|
|
11
|
+
qqmusic_api/data/api/mv.json,sha256=7joEYJjX8EiylqOnLikSHD5If2seIdghmQjXZa_Wjmw,735
|
|
12
|
+
qqmusic_api/data/api/search.json,sha256=bgOPK99p5I1haXrSGcYZXCwgH8sh8Ry8tBCmDrLeH0M,2481
|
|
13
|
+
qqmusic_api/data/api/singer.json,sha256=yj0WO6sFU4GCciYUBWjzvvfqrBh869doeOC2Pp5EI1Y,3
|
|
14
|
+
qqmusic_api/data/api/song.json,sha256=Dv1UyAjGvXn8aWMiJ-8bqWbyIU_q-BUpWsSiWinxZLg,3202
|
|
15
|
+
qqmusic_api/data/api/songlist.json,sha256=pkZCj4Lr284_FPaQu1yNfh6q-4WkcmykACllf2mxSsc,548
|
|
16
|
+
qqmusic_api/data/api/top.json,sha256=TwFneojiw-u0jdGZWSgdQSXX8G-fy3nf-PfhXli6yRI,555
|
|
17
|
+
qqmusic_api/data/file_type.json,sha256=s9Y9fhtD--UU5X2648NMUYTCi__g6vqQF5VTCorah6A,771
|
|
18
|
+
qqmusic_api/data/search_type.json,sha256=N4lYL2_QaxXeseZL0SCb9a4WaOKyiT6vbJpKP3fRJyg,154
|
|
19
|
+
qqmusic_api/exceptions.py,sha256=S0HhNTaJ-RMhnW8SDEJ0Y_ESmHSB5m06NogLqv98OxU,2475
|
|
20
|
+
qqmusic_api/settings.py,sha256=7G5xY4TPInHJ8yZ7qE6Q-Ry8LqsEyYZ6xqnk8YgSkF0,485
|
|
21
|
+
qqmusic_api/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
+
qqmusic_api/utils/common.py,sha256=tNuagktkLmjZt_ahJbsCVXaaIHQwYq_tEGaIZtqsR1o,3934
|
|
23
|
+
qqmusic_api/utils/credential.py,sha256=jWev35JlDWtzCzA0J8XxzVmij1HPTgq67gbEBnSvgsM,2376
|
|
24
|
+
qqmusic_api/utils/network.py,sha256=p3cg7IJPC2jySPkeGjrfwL9dpcxhHNG17GuCVCPWS4Y,7571
|
|
25
|
+
qqmusic_api/utils/qimei.py,sha256=Vk47ojgp5u6iFZMVTFN9xBbwtu9xT1Kg0DvxrfNsQ2g,8363
|
|
26
|
+
qqmusic_api_python-0.1.0.dist-info/LICENSE,sha256=dWHDhxdkwc4EVZ0xMf13_qTkjzPqbI1YL_1OzmZxaxU,1062
|
|
27
|
+
qqmusic_api_python-0.1.0.dist-info/METADATA,sha256=rjgOophHN1qzdWf60EQA_UuoX8MeD_7MB7FMomrhk30,2751
|
|
28
|
+
qqmusic_api_python-0.1.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
29
|
+
qqmusic_api_python-0.1.0.dist-info/RECORD,,
|