Skip to content

Commit

Permalink
refactor login process
Browse files Browse the repository at this point in the history
  • Loading branch information
cosven committed Jun 2, 2024
1 parent 883e8ca commit 59848e1
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 79 deletions.
28 changes: 4 additions & 24 deletions fuo_bilibili/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,41 +35,21 @@ def __init__(self):
' AppleWebKit/537.36 (KHTML, like Gecko)'
' Chrome/33.0.1750.152 Safari/537.36'
}
self._cookie = MozillaCookieJar(PLUGIN_API_COOKIEJAR_FILE)
self._session = requests.Session()
# UPDATE(2024-01-11): To make self.nav_info work, the header needs to be added
# UPDATE(2023-xx-xx): The header cause some API failing: self.nav_info
self._session.headers.update(self._headers)
self._session.cookies = self._cookie
self._wbi: Optional[NavInfoResponse.NavInfoResponseData.Wbi] = None

@staticmethod
def cookie_check():
if not PLUGIN_API_COOKIEJAR_FILE.exists():
return False
return True

def get_session(self):
return self._session

def get_cookies(self):
def get_cookiejar(self):
return self._session.cookies

@staticmethod
def remove_cookie():
PLUGIN_API_COOKIEJAR_FILE.unlink(missing_ok=True)

def from_cookiejar(self, jar: CookieJar):
for cookie in jar:
if 'bilibili.com' in cookie.domain:
self._cookie.set_cookie(cookie)
self._dump_cookie_to_file()

def load_cookies(self):
self._cookie.load()

def _dump_cookie_to_file(self):
self._cookie.save()
def from_cookiedict(self, cookies):
cookiejar = requests.cookies.cookiejar_from_dict(cookies)
self._session.cookies = cookiejar

def set_wbi(self, wbi: NavInfoResponse.NavInfoResponseData.Wbi):
self._wbi = wbi
Expand Down
1 change: 1 addition & 0 deletions fuo_bilibili/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

# Cookiejar file
PLUGIN_API_COOKIEJAR_FILE = PLUGIN_DATA_DIRECTORY / 'bilibili_api.cookie'
PLUGIN_API_COOKIEDICT_FILE = PLUGIN_DATA_DIRECTORY / 'bilibili_api_cookie.json'

# Ensure directories
PLUGIN_DATA_DIRECTORY.mkdir(parents=True, exist_ok=True)
Expand Down
12 changes: 9 additions & 3 deletions fuo_bilibili/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ def get_text_from_html(html):
return BeautifulSoup(html, features="html.parser").get_text()


def wrap_pic(pic):
if pic.startswith('//'):
return f'http:{pic}'
return pic


class BBriefAlbumModel(BriefAlbumModel):
cover: str = ''

Expand Down Expand Up @@ -112,7 +118,7 @@ def create_info_model(cls, response: VideoInfoResponse) -> 'BSongModel':
title=page.part,
artists=[],
duration=page.duration.total_seconds() * 1000,
pic_url=result.pic,
pic_url=wrap_pic(result.pic),
)
children.append(song)

Expand All @@ -134,7 +140,7 @@ def create_info_model(cls, response: VideoInfoResponse) -> 'BSongModel':
)],
duration=result.duration.total_seconds() * 1000,
lyric=lrc or '',
pic_url=result.pic,
pic_url=wrap_pic(result.pic),
children=children,
)

Expand Down Expand Up @@ -495,7 +501,7 @@ def create_video_model(cls, result: SearchResultVideo) -> 'VideoModel':
identifier=result.mid
)],
duration=result.duration.total_seconds(),
cover=result.pic,
cover=wrap_pic(result.pic),
play_count=result.play,
released=result.pubdate.strftime('%Y-%m-%d'),
)
Expand Down
14 changes: 3 additions & 11 deletions fuo_bilibili/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,17 +130,8 @@ def request_captcha(self) -> RequestCaptchaResponse.RequestCaptchaResponseData:
def request_key(self) -> RequestLoginKeyResponse:
return self._api.request_login_key()

def cookie_check(self):
return self._api.cookie_check()

def auth(self, _):
self._api.load_cookies()
try:
self._user = self.user_info()
except RuntimeError as re:
self._api.remove_cookie()
print(str(re) + ' 请重新登录')
return self._user
def auth(self, user):
self._user = user

def has_current_user(self) -> bool:
return self._user is not None
Expand All @@ -159,6 +150,7 @@ def user_info(self) -> UserModel:
name=data.uname,
avatar_url=data.face
)
print(user.avatar_url)
return user

def cookiejar_login(self, jar):
Expand Down
90 changes: 49 additions & 41 deletions fuo_bilibili/ui.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import asyncio
import logging
import json
from pathlib import Path
from typing import Optional

Expand All @@ -9,42 +10,53 @@
QAction, QInputDialog, QWidget
from feeluown.app.gui_app import GuiApp
from feeluown.gui import ProviderUiManager
from feeluown.gui.widgets.login import CookiesLoginDialog, InvalidCookies
from feeluown.library import UserModel
from feeluown.utils.aio import run_fn

from fuo_bilibili import __identifier__, __alias__, BilibiliProvider
from fuo_bilibili.api.schema.requests import PasswordLoginRequest, SendSmsCodeRequest, SmsCodeLoginRequest
from fuo_bilibili.api.schema.responses import RequestLoginKeyResponse
from fuo_bilibili.geetest.server import GeetestAuthServer
from fuo_bilibili.util import rsa_encrypt, get_random_available_port
from fuo_bilibili.const import PLUGIN_API_COOKIEDICT_FILE

logger = logging.getLogger(__name__)


class KeyringLoginWidget(QWidget):
finished = pyqtSignal()
class LoginDialog(CookiesLoginDialog):

def __init__(self, provider: BilibiliProvider, *args, **kwargs):
super().__init__(*args, **kwargs)
self._provider = provider
self._chrome_btn = QPushButton('从 Chrome 中读取 Cookie')
self.provider = provider

self._layout = QVBoxLayout(self)
self._layout.addWidget(self._chrome_btn)
self._chrome_btn.clicked.connect(self._get_cookies_from_chrome)
def setup_user(self, user):
self.provider.auth(user)

def _get_cookies_from_chrome(self):
from feeluown.utils.yt_dlp_cookies import load_cookies
jar = load_cookies(None, ['chrome'], None)
self._provider.cookiejar_login(jar)
self.finished.emit()
async def user_from_cookies(self, cookies):
if not cookies: # is None or empty
raise InvalidCookies('empty cookies')

@classmethod
def is_supported(cls):
self.provider._api.from_cookiedict(cookies)
try:
from feeluown.utils.yt_dlp_cookies import load_cookies # noqa
except ImportError:
return False
return True
user = await run_fn(self.provider.user_info)
except RuntimeError as e:
raise InvalidCookies(f'get user with cookies failed: {e}')
return user

def load_user_cookies(self):
if PLUGIN_API_COOKIEDICT_FILE.exists():
with PLUGIN_API_COOKIEDICT_FILE.open('r', encoding='utf-8') as f:
try:
cookie_dict = json.load(f)
except Exception:
logger.warning('parse cookies(json) failed')
return None
return cookie_dict

def dump_user_cookies(self, _, cookies):
with PLUGIN_API_COOKIEDICT_FILE.open('w', encoding='utf-8') as f:
json.dump(cookies, f, indent=2)


class BAuthDialog(QDialog):
Expand Down Expand Up @@ -197,16 +209,6 @@ def __init__(self, parent=None, provider=None, ui_manger=None):
self._pw_tab.hide()
# self._tab.addTab(self._sms_tab, '验证码登录')
# self._tab.addTab(self._pw_tab, '密码登录')
if KeyringLoginWidget.is_supported():
# keyring 登录
self._keyring_tab = KeyringLoginWidget(self._provider, parent=self._tab)
self._tab.addTab(self._keyring_tab, 'Keyring 登录')
self._keyring_tab.finished.connect(self._finish_keyring_login)
else:
self._tab.addTab(
QLabel('登录功能从 2023-08-01 开始,已经无法使用', self),
'提示',
)

# auth back signal
# noinspection PyUnresolvedReferences
Expand Down Expand Up @@ -303,9 +305,11 @@ def __init__(self, app: GuiApp, provider: BilibiliProvider):
desc='点击登录',
colorful_svg=(Path(__file__).parent / 'assets' / 'icon.svg').as_posix()
)
self._pvd_item.clicked.connect(self._login_or_get_user)
self._pvd_item.clicked.connect(self.login_or_go_home)
self._pvd_uimgr.add_item(self._pvd_item)
self.login_dialog = BLoginDialog(None, self._provider)

self.login_dialog = None

# 新建收藏夹
pl_header = self._app.ui.left_panel.playlists_header
pl_header.setContextMenuPolicy(Qt.ActionsContextMenu)
Expand All @@ -315,8 +319,6 @@ def __init__(self, app: GuiApp, provider: BilibiliProvider):
new_pl_action.triggered.connect(self.new_playlist)
self._initial_pages()

self.login_dialog.login_succeed.connect(self._login_or_get_user)

def new_playlist(self):
name, o1 = QInputDialog.getText(self._app.ui.left_panel.playlists_header, '新建收藏夹', '收藏夹标题')
if not o1:
Expand Down Expand Up @@ -370,14 +372,20 @@ async def load_user_content(self):
self._app.pl_uimgr.add(audio_fav_list)
self._app.pl_uimgr.add(audio_coll_list, is_fav=True)

def _login(self):
self._user = self._provider.auth(None)
if self._user is not None:
self._pvd_item.text = f'{__alias__}已登录:{self._user.name} UID:{self._user.identifier}'
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_get_user(self):
if self._provider.cookie_check():
self._login()
return
self.login_dialog.show()
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()

0 comments on commit 59848e1

Please sign in to comment.