Skip to content

Commit

Permalink
use ProviderUI
Browse files Browse the repository at this point in the history
  • Loading branch information
cosven committed Nov 19, 2024
1 parent 8bc8ceb commit 73d518f
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 85 deletions.
8 changes: 4 additions & 4 deletions fuo_bilibili/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@
from feeluown.app.gui_app import GuiApp

from fuo_bilibili.provider import BilibiliProvider
from fuo_bilibili.ui import BUiManager
from fuo_bilibili.ui import BProviderUi

provider = BilibiliProvider()
ui_mgr: Optional[BUiManager] = None


def init_config(config):
config.deffield('ENABLE_LIVE_ROOM_AS_VIDEO',
Expand All @@ -30,7 +28,8 @@ def enable(app: Union[App, GuiApp]):
provider.enable_live_room_as_video = app.config.bilibili.ENABLE_LIVE_ROOM_AS_VIDEO
app.library.register(provider)
if app.mode & App.GuiMode:
ui_mgr = BUiManager(app, provider)
ui_mgr = BProviderUi(app, provider)
app.pvd_ui_mgr.register(ui_mgr)


def disable(app: App):
Expand All @@ -39,3 +38,4 @@ def disable(app: App):
provider.close()
# noinspection PyUnresolvedReferences
app.providers.remove(provider.identifier)
app.pvd_ui_mgr.remove(provider.identifier)
2 changes: 1 addition & 1 deletion fuo_bilibili/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def clear_cache_by_url(urls: List[str]):
CACHE.pop(key)

def _get_csrf(self):
for cookie in self._cookie:
for cookie in self.get_cookiejar():
if cookie.name == 'bili_jct':
return cookie.value
raise RuntimeError('bili_jct not found')
Expand Down
19 changes: 18 additions & 1 deletion fuo_bilibili/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
FavoriteSeasonResourceResponse, HistoryLaterVideoResponse, HomeDynamicVideoResponse, UserInfoResponse, \
UserBestVideoResponse, UserVideoResponse, AudioFavoriteSongsResponse, AudioFavoriteListResponse, AudioPlaylist, \
AudioPlaylistSong, VideoHotCommentsResponse, SearchResultUser, LiveFeedListResponse, SearchResultLiveRoom, \
SearchResultMedia, MediaGetListResponse, VideoWeeklyListResponse
SearchResultMedia, MediaGetListResponse, VideoWeeklyListResponse, VideoMostPopularResponse
from fuo_bilibili.util import format_timedelta_to_hms

PROVIDER_ID = __identifier__
Expand Down Expand Up @@ -489,6 +489,23 @@ def create_live_model(cls, live: LiveFeedListResponse.LiveFeedListResponseData.L
cover=live.cover,
)

@classmethod
def create_popular_video_model(cls, result: VideoMostPopularResponse.VideoMostPopularResponseData.PopularVideo):
return VideoModel(
source=PROVIDER_ID,
identifier=result.bvid,
title=get_text_from_html(result.title),
artists=[BriefArtistModel(
source=PROVIDER_ID,
identifier=result.owner.mid,
name=result.owner.name
)],
duration=result.duration.total_seconds(),
cover=wrap_pic(result.pic),
play_count=result.stat.view,
released=result.pubdate.strftime('%Y-%m-%d'),
)

@classmethod
def create_video_model(cls, result: SearchResultVideo) -> 'VideoModel':
return VideoModel(
Expand Down
16 changes: 16 additions & 0 deletions fuo_bilibili/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,18 @@ def user_following(self) -> List[BriefArtistModel]:
name=user.uname,
) for user in resp.data.list]

def current_user_list_playlists(self):
p1 = self.special_playlists()
p2 = self.user_playlists(self.get_current_user().identifier)
p3 = self.audio_favorite_playlists()
p4 = self.audio_collected_playlists()
return p1 + p2 + p3 + p4

def current_user_fav_create_playlists_rd(self):
p1 = self.fav_playlists(self.get_current_user().identifier)
p2 = self.audio_collected_playlists()
return p1 + p2

def audio_favorite_playlists(self) -> List[BriefPlaylistModel]:
resp = self._api.audio_favorite_list(PaginatedRequest(ps=100, pn=1))
return BPlaylistModel.create_audio_model_list(resp)
Expand Down Expand Up @@ -622,6 +634,10 @@ def g():

return SequentialReader(g(), total)

def rec_a_collection_of_videos(self):
resp = self._api.video_most_popular()
return [BVideoModel.create_popular_video_model(v) for v in resp.data.list]

@property
def identifier(self):
return __identifier__
Expand Down
132 changes: 53 additions & 79 deletions fuo_bilibili/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
QAction, QInputDialog, QWidget
from feeluown.app.gui_app import GuiApp
from feeluown.gui import ProviderUiManager
from feeluown.gui.provider_ui import AbstractProviderUi, NavBtn
from feeluown.gui.widgets.login import CookiesLoginDialog, InvalidCookies
from feeluown.library import UserModel
from feeluown.utils.aio import run_fn
from feeluown.utils.dispatch import Signal

from fuo_bilibili import __identifier__, __alias__, BilibiliProvider
from fuo_bilibili.api.schema.requests import PasswordLoginRequest, SendSmsCodeRequest, SmsCodeLoginRequest
Expand Down Expand Up @@ -292,34 +294,58 @@ def _get_encrypted_password(self, key_data: RequestLoginKeyResponse):
return rsa_encrypt(salted_pw, key_data.key)


class BUiManager:
def __init__(self, app: GuiApp, provider: BilibiliProvider):
self._user: Optional[UserModel] = None
self._provider = provider
class BProviderUi(AbstractProviderUi):
def __init__(self, app: 'GuiApp', provider: BilibiliProvider):
self._app = app
self._pvd_uimgr: ProviderUiManager = app.pvd_uimgr
self._pvd_item = self._pvd_uimgr.create_item(
name=__identifier__,
text=__alias__,
symbol='📺',
desc='点击登录',
colorful_svg=(Path(__file__).parent / 'assets' / 'icon.svg').as_posix()
)
self._pvd_item.clicked.connect(self.login_or_go_home)
self._pvd_uimgr.add_item(self._pvd_item)

self._provider = provider
self._login_event = Signal()
self.login_dialog = None

# 新建收藏夹
pl_header = self._app.ui.left_panel.playlists_header
pl_header.setContextMenuPolicy(Qt.ActionsContextMenu)
new_pl_action = QAction('新建收藏夹', pl_header)
pl_header.addAction(new_pl_action)
# noinspection PyUnresolvedReferences
new_pl_action.triggered.connect(self.new_playlist)
self._initial_pages()
@property
def provider(self):
return self._provider

@property
def login_event(self):
return self._login_event

def login_or_go_home(self):
if not self._provider.has_current_user():
# keyring 登录
self.login_dialog = LoginDialog(
self._provider, 'https://bilibili.com', ['SESSDATA'])
self.login_dialog.login_succeed.connect(self.on_login_succeed)
self.login_dialog.autologin()
self.login_dialog.show()
else:
logger.info('already logged in')
self.login_event.emit(self, 2)

def get_colorful_svg(self) -> str:
return (Path(__file__).parent / 'assets' / 'icon.svg').as_posix()

def new_playlist(self):
def register_pages(self, route):
from fuo_bilibili.page_home import render as home_render
from fuo_bilibili.page_ranking import render as ranking_render

route('/providers/bilibili/home')(home_render)
route('/providers/bilibili/ranking')(ranking_render)

def list_nav_btns(self):
return [
NavBtn(
icon='📺',
text='我的首页',
cb=lambda: self._app.browser.goto(page='/providers/bilibili/home')
),
NavBtn(
icon='🔥',
text='全站热门',
cb=lambda: self._app.browser.goto(page='/providers/bilibili/ranking')
),
]

def create_playlist(self):
name, o1 = QInputDialog.getText(self._app.ui.left_panel.playlists_header, '新建收藏夹', '收藏夹标题')
if not o1:
return
Expand All @@ -334,58 +360,6 @@ def new_playlist(self):
except Exception as e:
QMessageBox.warning(self._app.ui.left_panel.playlists_header, '新建收藏夹失败', str(e))

def _initial_pages(self):
from fuo_bilibili.page_home import render as home_render
from fuo_bilibili.page_ranking import render as ranking_render
self._app.browser.route('/providers/bilibili/home')(home_render)
self._app.browser.route('/providers/bilibili/ranking')(ranking_render)

async def load_user_content(self):
left = self._app.ui.left_panel
left.playlists_con.show()
left.my_music_con.show()
# 音乐
mymusic_home_item = self._app.mymusic_uimgr.create_item('📺 我的首页')
mymusic_home_item.clicked.connect(
lambda: self._app.browser.goto(page='/providers/bilibili/home'),
weak=False)
mymusic_ranking_item = self._app.mymusic_uimgr.create_item('🔥 全站热门')
mymusic_ranking_item.clicked.connect(
lambda: self._app.browser.goto(page='/providers/bilibili/ranking'),
weak=False
)
self._app.mymusic_uimgr.clear()
self._app.mymusic_uimgr.add_item(mymusic_home_item)
self._app.mymusic_uimgr.add_item(mymusic_ranking_item)
# 歌单列表
self._app.pl_uimgr.clear()
# 视频区
special_playlists = self._provider.special_playlists()
playlists = self._provider.user_playlists(self._user.identifier)
fav_playlists = self._provider.fav_playlists(self._user.identifier)
self._app.pl_uimgr.add(special_playlists)
self._app.pl_uimgr.add(playlists)
self._app.pl_uimgr.add(fav_playlists, is_fav=True)
# 音频区
audio_fav_list = self._provider.audio_favorite_playlists()
audio_coll_list = self._provider.audio_collected_playlists()
self._app.pl_uimgr.add(audio_fav_list)
self._app.pl_uimgr.add(audio_coll_list, is_fav=True)

def after_login_succeed(self):
user = self._provider.get_current_user()
assert user is not None
self._user = user
self._pvd_item.text = f'{__alias__}已登录:{self._user.name} UID:{self._user.identifier}'
asyncio.ensure_future(self.load_user_content())

def login_or_go_home(self):
if self._provider._user is None:
# keyring 登录
self.login_dialog = LoginDialog(
self._provider, 'https://bilibili.com', ['SESSDATA'])
self.login_dialog.login_succeed.connect(self.after_login_succeed)
self.login_dialog.autologin()
self.login_dialog.show()
else:
self.after_login_succeed()
def on_login_succeed(self):
del self.login_dialog
self.login_event.emit(self, 1)

0 comments on commit 73d518f

Please sign in to comment.