fuo-qqmusic 1.0.6__py3-none-any.whl → 1.0.8__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.
Potentially problematic release.
This version of fuo-qqmusic might be problematic. Click here for more details.
- fuo_qqmusic/api.py +112 -0
- fuo_qqmusic/provider.py +66 -1
- fuo_qqmusic/provider_ui.py +3 -2
- fuo_qqmusic/schemas.py +1 -1
- {fuo_qqmusic-1.0.6.dist-info → fuo_qqmusic-1.0.8.dist-info}/METADATA +3 -3
- fuo_qqmusic-1.0.8.dist-info/RECORD +14 -0
- {fuo_qqmusic-1.0.6.dist-info → fuo_qqmusic-1.0.8.dist-info}/WHEEL +1 -1
- fuo_qqmusic-1.0.6.dist-info/RECORD +0 -14
- {fuo_qqmusic-1.0.6.dist-info → fuo_qqmusic-1.0.8.dist-info}/entry_points.txt +0 -0
- {fuo_qqmusic-1.0.6.dist-info → fuo_qqmusic-1.0.8.dist-info}/top_level.txt +0 -0
fuo_qqmusic/api.py
CHANGED
|
@@ -8,6 +8,7 @@ import math
|
|
|
8
8
|
import json
|
|
9
9
|
import random
|
|
10
10
|
import time
|
|
11
|
+
from enum import Enum
|
|
11
12
|
|
|
12
13
|
import requests
|
|
13
14
|
from .excs import QQIOError
|
|
@@ -286,6 +287,34 @@ class API(object):
|
|
|
286
287
|
resp = requests.get(url, params=params)
|
|
287
288
|
return resp.json()['data']
|
|
288
289
|
|
|
290
|
+
def playlist_remove_songs(self, playlist_id, song_id_list):
|
|
291
|
+
payload = {
|
|
292
|
+
'req_0': {
|
|
293
|
+
'method': 'DelSonglist',
|
|
294
|
+
'module': 'music.musicasset.PlaylistDetailWrite',
|
|
295
|
+
'param': {
|
|
296
|
+
'dirId': playlist_id, # int
|
|
297
|
+
'v_songInfo': [{'songId': int(song_id), 'songType': 0} for song_id in song_id_list]
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
js = self.rpc(payload)
|
|
302
|
+
return js['req_0']['code'] == 0
|
|
303
|
+
|
|
304
|
+
def playlist_add_songs(self, playlist_id, song_id_list):
|
|
305
|
+
payload = {
|
|
306
|
+
'req_0': {
|
|
307
|
+
'method': 'AddSonglist',
|
|
308
|
+
'module': 'music.musicasset.PlaylistDetailWrite',
|
|
309
|
+
'param': {
|
|
310
|
+
'dirId': int(playlist_id), # int
|
|
311
|
+
'v_songInfo': [{'songId': int(song_id), 'songType': 0} for song_id in song_id_list]
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
js = self.rpc(payload)
|
|
316
|
+
return js['req_0']['code'] == 0
|
|
317
|
+
|
|
289
318
|
def playlist_detail(self, pid, offset=0, limit=50):
|
|
290
319
|
url = api_base_url + '/qzone/fcg-bin/fcg_ucc_getcdinfo_byids_cp.fcg'
|
|
291
320
|
params = {
|
|
@@ -318,6 +347,7 @@ class API(object):
|
|
|
318
347
|
resp = requests.get(url, params=params, headers=self._headers,
|
|
319
348
|
cookies=self._cookies, timeout=self._timeout)
|
|
320
349
|
js = resp.json()
|
|
350
|
+
logger.debug(f"user detail response: {js}")
|
|
321
351
|
if js['code'] != 0:
|
|
322
352
|
raise CodeShouldBe0(js)
|
|
323
353
|
return js['data']
|
|
@@ -437,6 +467,7 @@ class API(object):
|
|
|
437
467
|
def rpc(self, payload):
|
|
438
468
|
if 'comm' not in payload:
|
|
439
469
|
payload['comm'] = self.get_common_params()
|
|
470
|
+
logger.debug(f"rpc payload: {payload}")
|
|
440
471
|
data_str = json.dumps(payload, ensure_ascii=False)
|
|
441
472
|
params = {
|
|
442
473
|
'_': int(round(time.time() * 1000)),
|
|
@@ -447,6 +478,7 @@ class API(object):
|
|
|
447
478
|
resp = requests.get(url, params=params, headers=self._headers,
|
|
448
479
|
cookies=self._cookies, timeout=self._timeout)
|
|
449
480
|
js = resp.json()
|
|
481
|
+
logger.debug(f"rpc response json: {js}")
|
|
450
482
|
CodeShouldBe0.check(js)
|
|
451
483
|
return js
|
|
452
484
|
|
|
@@ -717,5 +749,85 @@ class API(object):
|
|
|
717
749
|
return 'http://isure.stream.qqmusic.qq.com/{}'.format(midurlinfo[0]['purl'])
|
|
718
750
|
return ''
|
|
719
751
|
|
|
752
|
+
class DislikeListType(Enum):
|
|
753
|
+
singer = 2
|
|
754
|
+
song = 3
|
|
755
|
+
_style_unsupported = 4 # TODO: 这是什么?似乎是不喜欢的风格列表,不确定,暂时不支持
|
|
756
|
+
|
|
757
|
+
def get_dislike_list(self, page=1, type_=DislikeListType.song, last_id=0):
|
|
758
|
+
payload = {
|
|
759
|
+
"req_0": {
|
|
760
|
+
"module": "music.feedback.FeedbackBlack",
|
|
761
|
+
"method": "GetDislikeList",
|
|
762
|
+
"param": {
|
|
763
|
+
"Cmd": type_.value,
|
|
764
|
+
"Page": page,
|
|
765
|
+
"SongLastid": last_id if type_ == API.DislikeListType.song else 0,
|
|
766
|
+
"SingersLastid": (
|
|
767
|
+
last_id if type_ == API.DislikeListType.singer else 0
|
|
768
|
+
),
|
|
769
|
+
},
|
|
770
|
+
},
|
|
771
|
+
}
|
|
772
|
+
js = self.rpc(payload)
|
|
773
|
+
if type_ == API.DislikeListType.song:
|
|
774
|
+
return js["req_0"]["data"]["Songs"]
|
|
775
|
+
elif type_ == API.DislikeListType.singer:
|
|
776
|
+
return js["req_0"]["data"]["Singers"]
|
|
777
|
+
else:
|
|
778
|
+
raise QQIOError(f"Unknown dislike list type: {type_}")
|
|
779
|
+
|
|
780
|
+
def add_to_dislike_list(self, items, type_=DislikeListType.song):
|
|
781
|
+
req_param = {
|
|
782
|
+
"Singers": [],
|
|
783
|
+
"Songs": [],
|
|
784
|
+
"Styles": [],
|
|
785
|
+
"OnlyAdd": 1,
|
|
786
|
+
}
|
|
787
|
+
if type_ == API.DislikeListType.song:
|
|
788
|
+
req_param["Songs"] = items
|
|
789
|
+
elif type_ == API.DislikeListType.singer:
|
|
790
|
+
req_param["Singers"] = items
|
|
791
|
+
else:
|
|
792
|
+
raise QQIOError(f"Unknown dislike list type: {type_}")
|
|
793
|
+
|
|
794
|
+
payload = {
|
|
795
|
+
"req_0": {
|
|
796
|
+
"module": "music.feedback.FeedbackBlack",
|
|
797
|
+
"method": "AddDislike",
|
|
798
|
+
"param": req_param,
|
|
799
|
+
},
|
|
800
|
+
}
|
|
801
|
+
js = self.rpc(payload)
|
|
802
|
+
# Response example, {'code': 0, 'data': {'Retcode': 0, 'Msg': '', 'Token': ''}}
|
|
803
|
+
CodeShouldBe0.check(js['req_0'])
|
|
804
|
+
return js['req_0']['data']
|
|
805
|
+
|
|
806
|
+
def remove_from_dislike_list(self, items, type_=DislikeListType.song):
|
|
807
|
+
req_param = {
|
|
808
|
+
"Singers": [],
|
|
809
|
+
"Songs": [],
|
|
810
|
+
"Styles": [],
|
|
811
|
+
"OnlyAdd": 0,
|
|
812
|
+
}
|
|
813
|
+
if type_ == API.DislikeListType.song:
|
|
814
|
+
req_param["Songs"] = items
|
|
815
|
+
elif type_ == API.DislikeListType.singer:
|
|
816
|
+
req_param["Singers"] = items
|
|
817
|
+
else:
|
|
818
|
+
raise QQIOError(f"Unknown dislike list type: {type_}")
|
|
819
|
+
|
|
820
|
+
payload = {
|
|
821
|
+
"req_0": {
|
|
822
|
+
"module": "music.feedback.FeedbackBlack",
|
|
823
|
+
"method": "CancelDislike",
|
|
824
|
+
"param": req_param,
|
|
825
|
+
},
|
|
826
|
+
}
|
|
827
|
+
js = self.rpc(payload)
|
|
828
|
+
CodeShouldBe0.check(js)
|
|
829
|
+
CodeShouldBe0.check(js['req_0'])
|
|
830
|
+
return js['req_0']['data']
|
|
831
|
+
|
|
720
832
|
|
|
721
833
|
api = API()
|
fuo_qqmusic/provider.py
CHANGED
|
@@ -4,6 +4,7 @@ from feeluown.excs import ModelNotFound
|
|
|
4
4
|
from feeluown.library import (
|
|
5
5
|
AbstractProvider,
|
|
6
6
|
BriefSongModel,
|
|
7
|
+
BriefPlaylistModel,
|
|
7
8
|
PlaylistModel,
|
|
8
9
|
Collection,
|
|
9
10
|
CollectionType,
|
|
@@ -23,12 +24,17 @@ from feeluown.library import (
|
|
|
23
24
|
SupportsPlaylistGet,
|
|
24
25
|
SupportsPlaylistSongsReader,
|
|
25
26
|
SupportsRecACollectionOfSongs,
|
|
27
|
+
SupportsCurrentUserDislikeSongsReader,
|
|
28
|
+
SupportsCurrentUserDislikeAddSong,
|
|
29
|
+
SupportsCurrentUserDislikeRemoveSong,
|
|
30
|
+
SupportsCurrentUserChanged,
|
|
26
31
|
SimpleSearchResult,
|
|
27
32
|
SearchType,
|
|
28
33
|
ModelType,
|
|
29
34
|
UserModel,
|
|
30
35
|
)
|
|
31
36
|
from feeluown.media import Media, Quality
|
|
37
|
+
from feeluown.utils.dispatch import Signal
|
|
32
38
|
from feeluown.utils.reader import create_reader, SequentialReader
|
|
33
39
|
from .api import API
|
|
34
40
|
from .login import read_cookies
|
|
@@ -53,6 +59,9 @@ class Supports(
|
|
|
53
59
|
SupportsPlaylistSongsReader,
|
|
54
60
|
SupportsRecACollectionOfSongs,
|
|
55
61
|
SupportsAlbumSongsReader,
|
|
62
|
+
SupportsCurrentUserDislikeSongsReader,
|
|
63
|
+
SupportsCurrentUserDislikeAddSong,
|
|
64
|
+
SupportsCurrentUserDislikeRemoveSong,
|
|
56
65
|
Protocol,
|
|
57
66
|
):
|
|
58
67
|
pass
|
|
@@ -70,6 +79,7 @@ class QQProvider(AbstractProvider, ProviderV2):
|
|
|
70
79
|
def __init__(self):
|
|
71
80
|
super().__init__()
|
|
72
81
|
self.api = API()
|
|
82
|
+
self.current_user_changed = Signal()
|
|
73
83
|
|
|
74
84
|
def _(self) -> Supports:
|
|
75
85
|
return self
|
|
@@ -89,6 +99,7 @@ class QQProvider(AbstractProvider, ProviderV2):
|
|
|
89
99
|
self.auth(user)
|
|
90
100
|
else:
|
|
91
101
|
logger.info(f'Auto login failed: {err}')
|
|
102
|
+
self.current_user_changed.emit(user)
|
|
92
103
|
|
|
93
104
|
def try_get_user_from_cookies(self, cookies) -> Tuple[Optional[UserModel], str]:
|
|
94
105
|
if not cookies: # is None or empty
|
|
@@ -270,6 +281,22 @@ class QQProvider(AbstractProvider, ProviderV2):
|
|
|
270
281
|
data = self.api.playlist_detail(int(identifier), limit=1000)
|
|
271
282
|
return _deserialize(data, QQPlaylistSchema)
|
|
272
283
|
|
|
284
|
+
def playlist_add_song(self, playlist, song):
|
|
285
|
+
# FIXME: 目前 playlist 相关接口用的都是 diss 结构体,而这里需要一个 dirid。
|
|
286
|
+
# 平台方也提供了 dir 相关的接口,我大胆猜测,diss 是一套老接口。
|
|
287
|
+
playlist._cache.pop("songs", None)
|
|
288
|
+
dirid = self._get_dirid_by_playlist_id(playlist.identifier)
|
|
289
|
+
return self.api.playlist_add_songs(dirid, [song.identifier])
|
|
290
|
+
|
|
291
|
+
def playlist_remove_song(self, playlist, song):
|
|
292
|
+
playlist._cache.pop("songs", None)
|
|
293
|
+
dirid = self._get_dirid_by_playlist_id(playlist.identifier)
|
|
294
|
+
return self.api.playlist_remove_songs(dirid, [song.identifier])
|
|
295
|
+
|
|
296
|
+
def _get_dirid_by_playlist_id(self, playlist_id):
|
|
297
|
+
data = self.api.playlist_detail(int(playlist_id), limit=1)
|
|
298
|
+
return data["dirid"]
|
|
299
|
+
|
|
273
300
|
def playlist_create_songs_rd(self, playlist):
|
|
274
301
|
songs = self._model_cache_get_or_fetch(playlist, "songs")
|
|
275
302
|
return create_reader(songs)
|
|
@@ -371,7 +398,13 @@ class QQProvider(AbstractProvider, ProviderV2):
|
|
|
371
398
|
if user is None:
|
|
372
399
|
return []
|
|
373
400
|
playlists = self._model_cache_get_or_fetch(user, "playlists")
|
|
374
|
-
|
|
401
|
+
fav_pid = self._model_cache_get_or_fetch(user, "fav_pid")
|
|
402
|
+
my_love = BriefPlaylistModel(
|
|
403
|
+
source=SOURCE,
|
|
404
|
+
identifier=str(fav_pid),
|
|
405
|
+
name='我喜欢'
|
|
406
|
+
)
|
|
407
|
+
return [my_love] + playlists
|
|
375
408
|
|
|
376
409
|
def current_user_fav_create_songs_rd(self):
|
|
377
410
|
user = self.get_current_user()
|
|
@@ -405,6 +438,9 @@ class QQProvider(AbstractProvider, ProviderV2):
|
|
|
405
438
|
return create_reader([])
|
|
406
439
|
mid = self._model_cache_get_or_fetch(user, "mid")
|
|
407
440
|
playlists = self.api.user_favorite_playlists(user.identifier, mid)
|
|
441
|
+
# HACK: 给 playlist 加一个 disstid 字段,这样可以兼容 QQPlaylistSchema
|
|
442
|
+
for playlist in playlists:
|
|
443
|
+
playlist["disstid"] = playlist["dissid"]
|
|
408
444
|
return [_deserialize(playlist, QQPlaylistSchema) for playlist in playlists]
|
|
409
445
|
|
|
410
446
|
def has_current_user(self):
|
|
@@ -417,6 +453,35 @@ class QQProvider(AbstractProvider, ProviderV2):
|
|
|
417
453
|
data_songs = self.api.song_similar(int(song.identifier))
|
|
418
454
|
return [_deserialize(data_song, QQSongSchema) for data_song in data_songs]
|
|
419
455
|
|
|
456
|
+
def current_user_dislike_create_songs_rd(self):
|
|
457
|
+
user = self.get_current_user()
|
|
458
|
+
if user is None:
|
|
459
|
+
return create_reader([])
|
|
460
|
+
# FIXME: 如果用户的黑名单歌曲数量较多的话,这样处理则是不够的
|
|
461
|
+
items = self.api.get_dislike_list(1, API.DislikeListType.song, 0)
|
|
462
|
+
songs = []
|
|
463
|
+
for item in items:
|
|
464
|
+
name = item['Name']
|
|
465
|
+
title, artists_name = name.split(' - ')
|
|
466
|
+
song = BriefSongModel(
|
|
467
|
+
source=SOURCE,
|
|
468
|
+
identifier=item['ID'],
|
|
469
|
+
title=title,
|
|
470
|
+
artists_name=artists_name,
|
|
471
|
+
)
|
|
472
|
+
songs.append(song)
|
|
473
|
+
return create_reader(songs)
|
|
474
|
+
|
|
475
|
+
def current_user_dislike_add_song(self, song):
|
|
476
|
+
items = [{'ID': song.identifier}]
|
|
477
|
+
js = self.api.add_to_dislike_list(items, API.DislikeListType.song)
|
|
478
|
+
return js.get('Retcode') == 0
|
|
479
|
+
|
|
480
|
+
def current_user_dislike_remove_song(self, song):
|
|
481
|
+
items = [{'ID': song.identifier}]
|
|
482
|
+
js = self.api.remove_from_dislike_list(items, API.DislikeListType.song)
|
|
483
|
+
return js.get('Retcode') == 0
|
|
484
|
+
|
|
420
485
|
|
|
421
486
|
def _deserialize(data, schema_cls):
|
|
422
487
|
schema = schema_cls()
|
fuo_qqmusic/provider_ui.py
CHANGED
|
@@ -39,8 +39,9 @@ class ProviderUI(AbstractProviderUi):
|
|
|
39
39
|
#
|
|
40
40
|
# - keys: ['skey']
|
|
41
41
|
url = os.getenv('FUO_QQMUSIC_LOGIN_URL', 'https://y.qq.com')
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
keys_str = os.getenv('FUO_QQMUSIC_LOGIN_COOKIE_KEYS',
|
|
43
|
+
'qqmusic_key,wxuin|qqmusic_key,uin')
|
|
44
|
+
self._dialog = LoginDialog(url, [keys.split(',') for keys in keys_str.split('|')])
|
|
44
45
|
self._dialog.login_succeed.connect(self.on_login_succeed)
|
|
45
46
|
self._dialog.show()
|
|
46
47
|
self._dialog.autologin()
|
fuo_qqmusic/schemas.py
CHANGED
|
@@ -271,7 +271,7 @@ class QQAlbumSchema(Schema):
|
|
|
271
271
|
|
|
272
272
|
|
|
273
273
|
class QQPlaylistSchema(Schema):
|
|
274
|
-
identifier = fields.Int(required=True, data_key="
|
|
274
|
+
identifier = fields.Int(required=True, data_key="disstid")
|
|
275
275
|
name = fields.Str(required=True, data_key="dissname")
|
|
276
276
|
cover = fields.Str(required=True, data_key="logo")
|
|
277
277
|
# songs field maybe null, though it can't be null in model
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fuo_qqmusic
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.8
|
|
4
4
|
Summary: feeluown qqmusic plugin
|
|
5
5
|
Home-page: https://github.com/feeluown/feeluown-qqmusic
|
|
6
6
|
Author: Cosven
|
|
@@ -13,9 +13,9 @@ Classifier: Programming Language :: Python :: 3.7
|
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.8
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.9
|
|
15
15
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
-
Requires-Dist: feeluown>=4.1.
|
|
16
|
+
Requires-Dist: feeluown>=4.1.13
|
|
17
17
|
Requires-Dist: requests
|
|
18
|
-
Requires-Dist: marshmallow
|
|
18
|
+
Requires-Dist: marshmallow<4.0.0,>=3.0
|
|
19
19
|
Dynamic: author
|
|
20
20
|
Dynamic: author-email
|
|
21
21
|
Dynamic: classifier
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
fuo_qqmusic/__init__.py,sha256=YxZHAp5Qaye5B5V8GBPyxqnEUe-FcwUv6TiF_29qBEs,537
|
|
2
|
+
fuo_qqmusic/api.py,sha256=vzsPBhoivJs_LA_L8g7gR49o3jqtH_xpt3LInrBWBfI,28548
|
|
3
|
+
fuo_qqmusic/consts.py,sha256=9VFc9yE6z6c0IzK03PQTEO0JqgXi37RahEvZRP-A4Dk,185
|
|
4
|
+
fuo_qqmusic/excs.py,sha256=SBcER_wESjvui6a0Li1dX5utep4ouDS7HaTXqXPOQiA,160
|
|
5
|
+
fuo_qqmusic/login.py,sha256=zNPPncKl1Pr8uYBbLrdPlVJyKBsNfS2FotRfn9l3LEA,542
|
|
6
|
+
fuo_qqmusic/provider.py,sha256=S3gcS0od5nF-7_YLZ_VFGRSpycr4LMH31sexqDFvO_0,20270
|
|
7
|
+
fuo_qqmusic/provider_ui.py,sha256=YzYVnst6OhYH8ii0rHrfZ6T41zJk844rkxL3E4gyD4Y,2459
|
|
8
|
+
fuo_qqmusic/schemas.py,sha256=bS6PgqAypCo-4I11_iVyu_ZgBXxmkoVQ9cRIQDymjlc,12129
|
|
9
|
+
fuo_qqmusic/assets/icon.svg,sha256=o48VTiHroJU6S2g8LbxfnK25G2QW3d1XtQZKoL3ZMGA,1216
|
|
10
|
+
fuo_qqmusic-1.0.8.dist-info/METADATA,sha256=OIWBsFTaCfZJQ3Mk0Mudvur_JzErhXiDNYOko6retJk,811
|
|
11
|
+
fuo_qqmusic-1.0.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
12
|
+
fuo_qqmusic-1.0.8.dist-info/entry_points.txt,sha256=XUL7UwcsLZEuEbBJIcsFemC3BiYb7dSTiXB9r6SJ5zY,39
|
|
13
|
+
fuo_qqmusic-1.0.8.dist-info/top_level.txt,sha256=Qn_g3dRwtoVZgVPZ9uRehspXi62T-E1x9_kLIdYFic4,12
|
|
14
|
+
fuo_qqmusic-1.0.8.dist-info/RECORD,,
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
fuo_qqmusic/__init__.py,sha256=YxZHAp5Qaye5B5V8GBPyxqnEUe-FcwUv6TiF_29qBEs,537
|
|
2
|
-
fuo_qqmusic/api.py,sha256=bFgr9eyRMrBhsQC8qR1sJ5SN616tdn06eXG6igZ6_ms,24587
|
|
3
|
-
fuo_qqmusic/consts.py,sha256=9VFc9yE6z6c0IzK03PQTEO0JqgXi37RahEvZRP-A4Dk,185
|
|
4
|
-
fuo_qqmusic/excs.py,sha256=SBcER_wESjvui6a0Li1dX5utep4ouDS7HaTXqXPOQiA,160
|
|
5
|
-
fuo_qqmusic/login.py,sha256=zNPPncKl1Pr8uYBbLrdPlVJyKBsNfS2FotRfn9l3LEA,542
|
|
6
|
-
fuo_qqmusic/provider.py,sha256=LqFB18PtXVBVFl2SfDoaQea6R4aq16My9PGrhhLotPg,17478
|
|
7
|
-
fuo_qqmusic/provider_ui.py,sha256=K70BjKvlx4h6gVYqeHOZhP68nnUWH2_mFbUK3jjvJ5U,2366
|
|
8
|
-
fuo_qqmusic/schemas.py,sha256=Sbka-YuK3UTn26CbfwOb0ZfB6XmiJHW-ibCLThj49VQ,12128
|
|
9
|
-
fuo_qqmusic/assets/icon.svg,sha256=o48VTiHroJU6S2g8LbxfnK25G2QW3d1XtQZKoL3ZMGA,1216
|
|
10
|
-
fuo_qqmusic-1.0.6.dist-info/METADATA,sha256=nhPvAwYN2IzTfRbkBivKvgsaZtiCZroqPKIdfhZZsRc,803
|
|
11
|
-
fuo_qqmusic-1.0.6.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
|
12
|
-
fuo_qqmusic-1.0.6.dist-info/entry_points.txt,sha256=XUL7UwcsLZEuEbBJIcsFemC3BiYb7dSTiXB9r6SJ5zY,39
|
|
13
|
-
fuo_qqmusic-1.0.6.dist-info/top_level.txt,sha256=Qn_g3dRwtoVZgVPZ9uRehspXi62T-E1x9_kLIdYFic4,12
|
|
14
|
-
fuo_qqmusic-1.0.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|