fuo-qqmusic 1.0.5__py3-none-any.whl → 1.0.6__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 CHANGED
@@ -518,6 +518,33 @@ class API(object):
518
518
  js = self.rpc(payload)
519
519
  return js['songlist']['data']['tracks']
520
520
 
521
+ def get_diss_info(self, dissid, offset=0, limit=50):
522
+ """获取歌单的详情
523
+
524
+ 这是一种特殊的歌单,它的内容是动态的,由官方生成。比如“百万收藏”。
525
+
526
+ :param dissid: int, 举个例子 211111 是百万收藏。
527
+ :return: 参考 fixtures/get_diss_info.json
528
+ """
529
+ payload = {
530
+ 'req': {
531
+ "module": "music.srfDissInfo.aiDissInfo",
532
+ "method":"uniform_get_Dissinfo",
533
+ "param": {
534
+ "disstid":dissid,
535
+ "userinfo":1, # 不懂啥意思
536
+ "tag":1, # 不懂啥意思
537
+ "orderlist":1,
538
+ "song_begin": offset,
539
+ "song_num": limit,
540
+ "onlysonglist":0,
541
+ "enc_host_uin":"" # 注:即使登录了,这个也是空
542
+ }
543
+ }
544
+ }
545
+ js = self.rpc(payload)
546
+ return js['req']['data']
547
+
521
548
  def get_song_url(self, song_mid):
522
549
  uin = self._uin
523
550
  songvkey = str(random.random()).replace("0.", "")
fuo_qqmusic/login.py ADDED
@@ -0,0 +1,24 @@
1
+ import json
2
+ import os
3
+
4
+ from feeluown.consts import DATA_DIR
5
+
6
+ USER_INFO_FILE = DATA_DIR + '/qqmusic_user_info.json'
7
+
8
+
9
+ def read_cookies():
10
+ if os.path.exists(USER_INFO_FILE):
11
+ # if the file is broken, just raise error
12
+ with open(USER_INFO_FILE) as f:
13
+ return json.load(f).get('cookies', None)
14
+
15
+
16
+ def write_cookies(user, cookies):
17
+ js = {
18
+ 'identifier': user.identifier,
19
+ 'name': user.name,
20
+ 'cookies': cookies
21
+ }
22
+ with open(USER_INFO_FILE, 'w') as f:
23
+ json.dump(js, f, indent=2)
24
+
fuo_qqmusic/provider.py CHANGED
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import List, Optional, Protocol
2
+ from typing import List, Optional, Protocol, Tuple
3
3
  from feeluown.excs import ModelNotFound
4
4
  from feeluown.library import (
5
5
  AbstractProvider,
@@ -26,10 +26,13 @@ from feeluown.library import (
26
26
  SimpleSearchResult,
27
27
  SearchType,
28
28
  ModelType,
29
+ UserModel,
29
30
  )
30
31
  from feeluown.media import Media, Quality
31
32
  from feeluown.utils.reader import create_reader, SequentialReader
32
33
  from .api import API
34
+ from .login import read_cookies
35
+ from .excs import QQIOError
33
36
 
34
37
 
35
38
  logger = logging.getLogger(__name__)
@@ -79,6 +82,31 @@ class QQProvider(AbstractProvider, ProviderV2):
79
82
  def name(self):
80
83
  return "QQ 音乐"
81
84
 
85
+ def auto_login(self):
86
+ cookies = read_cookies()
87
+ user, err = self.try_get_user_from_cookies(cookies)
88
+ if user:
89
+ self.auth(user)
90
+ else:
91
+ logger.info(f'Auto login failed: {err}')
92
+
93
+ def try_get_user_from_cookies(self, cookies) -> Tuple[Optional[UserModel], str]:
94
+ if not cookies: # is None or empty
95
+ return None, 'empty cookies'
96
+
97
+ uin = provider.api.get_uin_from_cookies(cookies)
98
+ if uin is None:
99
+ return None, "can't extract user info from cookies"
100
+
101
+ provider.api.set_cookies(cookies)
102
+ # try to extract current user
103
+ try:
104
+ user = provider.user_get(uin)
105
+ except QQIOError:
106
+ provider.api.set_cookies(None)
107
+ return None, 'get user info with cookies failed, expired cookies?'
108
+ return user, ''
109
+
82
110
  def use_model_v2(self, mtype):
83
111
  return mtype in (
84
112
  ModelType.song,
@@ -259,6 +287,27 @@ class QQProvider(AbstractProvider, ProviderV2):
259
287
  pl["logo"] = pl["cover"]
260
288
  return [_deserialize(playlist, QQPlaylistSchema) for playlist in playlists]
261
289
 
290
+ def rec_list_daily_songs(self):
291
+ # TODO: cache API result
292
+ feed = self.api.get_recommend_feed()
293
+ card = None
294
+ for shelf_ in feed['v_shelf']:
295
+ if 'moduleID' not in shelf_['extra_info']:
296
+ for batch in shelf_['v_niche']:
297
+ for card in batch['v_card']:
298
+ if (
299
+ card['extra_info'].get('moduleID', '').startswith('recforyou')
300
+ and card['jumptype'] == 10014 # 10014->playlist
301
+ ):
302
+ card = card
303
+ break
304
+ if card is None:
305
+ logger.warning("No daily songs found")
306
+ return []
307
+ playlist_id = card['id']
308
+ playlist = self.playlist_get(playlist_id)
309
+ return self.playlist_create_songs_rd(playlist).readall()
310
+
262
311
  def rec_list_daily_playlists(self):
263
312
  # TODO: cache API result
264
313
  feed = self.api.get_recommend_feed()
@@ -11,20 +11,11 @@ from feeluown.app.gui_app import GuiApp
11
11
 
12
12
  from .provider import provider
13
13
  from .excs import QQIOError
14
+ from .login import read_cookies, write_cookies
14
15
 
15
16
  logger = logging.getLogger(__name__)
16
17
 
17
18
 
18
- USER_INFO_FILE = DATA_DIR + '/qqmusic_user_info.json'
19
-
20
-
21
- def read_cookies():
22
- if os.path.exists(USER_INFO_FILE):
23
- # if the file is broken, just raise error
24
- with open(USER_INFO_FILE) as f:
25
- return json.load(f).get('cookies', None)
26
-
27
-
28
19
  class ProviderUI(AbstractProviderUi):
29
20
  def __init__(self, app: GuiApp):
30
21
  self._app = app
@@ -72,31 +63,13 @@ class LoginDialog(CookiesLoginDialog):
72
63
  provider._user = user
73
64
 
74
65
  async def user_from_cookies(self, cookies):
75
- if not cookies: # is None or empty
76
- raise InvalidCookies('empty cookies')
77
-
78
- uin = provider.api.get_uin_from_cookies(cookies)
79
- if uin is None:
80
- raise InvalidCookies("can't extract user info from cookies")
81
-
82
- provider.api.set_cookies(cookies)
83
- # try to extract current user
84
- try:
85
- user = await run_fn(provider.user_get, uin)
86
- except QQIOError:
87
- provider.api.set_cookies(None)
88
- raise InvalidCookies('get user info with cookies failed, expired cookies?')
89
- else:
66
+ user, err = await run_fn(provider.try_get_user_from_cookies, cookies)
67
+ if user:
90
68
  return user
69
+ raise InvalidCookies(err)
91
70
 
92
71
  def load_user_cookies(self):
93
72
  return read_cookies()
94
73
 
95
74
  def dump_user_cookies(self, user, cookies):
96
- js = {
97
- 'identifier': user.identifier,
98
- 'name': user.name,
99
- 'cookies': cookies
100
- }
101
- with open(USER_INFO_FILE, 'w') as f:
102
- json.dump(js, f, indent=2)
75
+ write_cookies(user, cookies)
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: fuo_qqmusic
3
- Version: 1.0.5
3
+ Version: 1.0.6
4
4
  Summary: feeluown qqmusic plugin
5
5
  Home-page: https://github.com/feeluown/feeluown-qqmusic
6
6
  Author: Cosven
@@ -13,7 +13,13 @@ 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.3)
16
+ Requires-Dist: feeluown>=4.1.3
17
17
  Requires-Dist: requests
18
- Requires-Dist: marshmallow (>=3.0)
19
-
18
+ Requires-Dist: marshmallow>=3.0
19
+ Dynamic: author
20
+ Dynamic: author-email
21
+ Dynamic: classifier
22
+ Dynamic: home-page
23
+ Dynamic: keywords
24
+ Dynamic: requires-dist
25
+ Dynamic: summary
@@ -0,0 +1,14 @@
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (72.1.0)
2
+ Generator: setuptools (80.3.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,13 +0,0 @@
1
- fuo_qqmusic/__init__.py,sha256=YxZHAp5Qaye5B5V8GBPyxqnEUe-FcwUv6TiF_29qBEs,537
2
- fuo_qqmusic/api.py,sha256=w_anRMxAqL9FaMJVRmZ3A_uV4rzr7_S_1xMjZf-uovY,23597
3
- fuo_qqmusic/consts.py,sha256=9VFc9yE6z6c0IzK03PQTEO0JqgXi37RahEvZRP-A4Dk,185
4
- fuo_qqmusic/excs.py,sha256=SBcER_wESjvui6a0Li1dX5utep4ouDS7HaTXqXPOQiA,160
5
- fuo_qqmusic/provider.py,sha256=JmQtjPVPsaZ1n12phJDd_Ll3Y83RfaHb5S6i0d1xrjw,15669
6
- fuo_qqmusic/provider_ui.py,sha256=UKmzK6SImyWZe_wtkjcfXH_gy2XXbcnnI4Er0fICM6I,3197
7
- fuo_qqmusic/schemas.py,sha256=Sbka-YuK3UTn26CbfwOb0ZfB6XmiJHW-ibCLThj49VQ,12128
8
- fuo_qqmusic/assets/icon.svg,sha256=o48VTiHroJU6S2g8LbxfnK25G2QW3d1XtQZKoL3ZMGA,1216
9
- fuo_qqmusic-1.0.5.dist-info/METADATA,sha256=EgB-48xvBBqTnxxGYFAjK3rqBpaYK6hS5Csvdx5ubAM,675
10
- fuo_qqmusic-1.0.5.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
11
- fuo_qqmusic-1.0.5.dist-info/entry_points.txt,sha256=XUL7UwcsLZEuEbBJIcsFemC3BiYb7dSTiXB9r6SJ5zY,39
12
- fuo_qqmusic-1.0.5.dist-info/top_level.txt,sha256=Qn_g3dRwtoVZgVPZ9uRehspXi62T-E1x9_kLIdYFic4,12
13
- fuo_qqmusic-1.0.5.dist-info/RECORD,,