Skip to content

Commit

Permalink
gui: enable login with keyring (#795)
Browse files Browse the repository at this point in the history
  • Loading branch information
cosven committed Feb 16, 2024
1 parent 2cc13e5 commit 3b64331
Showing 1 changed file with 61 additions and 1 deletion.
62 changes: 61 additions & 1 deletion feeluown/gui/widgets/login.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,46 @@
import json
from http.cookies import SimpleCookie
from urllib.parse import urlparse

from PyQt5.QtCore import pyqtSignal, Qt
from PyQt5.QtWidgets import QDialog, QTextEdit, QPushButton, \
QVBoxLayout, QLabel

try:
from feeluown.gui.widgets.weblogin import WebLoginView
except ImportError:
has_webengine = False
else:
has_webengine = True

try:
from feeluown.utils.yt_dlp_cookies import load_cookies # noqa
except ImportError:
can_load_keyring_cookies = False
else:
can_load_keyring_cookies = True

from feeluown.utils import aio


def try_get_domain_from_uri(uri):
"""
xx.yy.com -> yy.com
https://xx.yy.com -> yy.com
"""
try:
result = urlparse(uri)
except ValueError:
return ''
# When uri is 'xx.yy.com', then netloc is empty.
netloc = result.netloc
if not netloc:
netloc = result.path
if netloc:
return '.'.join(netloc.split('.')[-2:])
return netloc


class InvalidCookies(Exception):
pass

Expand Down Expand Up @@ -46,7 +73,7 @@ class CookiesLoginDialog(LoginDialog):
One usage example: feeluown-qqmusic.
"""

def __init__(self, uri=None, required_cookies_fields=None):
def __init__(self, uri=None, required_cookies_fields=None, domain=None):
if has_webengine and uri and required_cookies_fields:
use_webview = True
flags = Qt.Window
Expand All @@ -57,12 +84,17 @@ def __init__(self, uri=None, required_cookies_fields=None):
super().__init__(None, flags)
self._use_webview = use_webview
self._uri = uri
if domain is None and uri is not None:
self._domain = try_get_domain_from_uri(uri)
self._required_cookies_fields = required_cookies_fields

self.cookies_text_edit = QTextEdit(self)
self.hint_label = QLabel(self)
self.login_btn = QPushButton('登录', self)
self.weblogin_btn = QPushButton('网页登录', self)
self.chrome_btn = QPushButton('从 Chrome 中读取 Cookie')
self.firefox_btn = QPushButton('从 Firefox 中读取 Cookie')
self.edge_btn = QPushButton('从 Edge 中读取 Cookie')

self.hint_label.setTextFormat(Qt.RichText)

Expand All @@ -71,6 +103,9 @@ def __init__(self, uri=None, required_cookies_fields=None):
self._layout.addWidget(self.hint_label)
self._layout.addWidget(self.login_btn)
self._layout.addWidget(self.weblogin_btn)
self._layout.addWidget(self.chrome_btn)
self._layout.addWidget(self.firefox_btn)
self._layout.addWidget(self.edge_btn)

self.cookies_text_edit.setAcceptRichText(False)
self.cookies_text_edit.setPlaceholderText(
Expand All @@ -88,6 +123,15 @@ def __init__(self, uri=None, required_cookies_fields=None):
else:
# hide the button if provider does not support
self.weblogin_btn.hide()

if not (can_load_keyring_cookies and self._domain):
self.chrome_btn.setDisabled(True)
self.edge_btn.setDisabled(True)
self.firefox_btn.setDisabled(True)

self.chrome_btn.clicked.connect(lambda: self._start_keyring_login('chrome'))
self.firefox_btn.clicked.connect(lambda: self._start_keyring_login('firefox'))
self.edge_btn.clicked.connect(lambda: self._start_keyring_login('edge'))
self.login_btn.clicked.connect(lambda: aio.create_task(self.login()))
self.login_succeed.connect(self.hide)

Expand All @@ -96,6 +140,22 @@ def _start_web_login(self):
self._web_login.succeed.connect(self._on_web_login_succeed)
self._web_login.show()

def _start_keyring_login(self, browser):
cookie_dict = self._get_cookies_from_browser(browser)
self.cookies_text_edit.setText(json.dumps(cookie_dict, indent=2))
aio.create_task(self.login())

def _get_cookies_from_browser(self, browser):
"""
:param browser: chrome,firefox,edge
"""
jar = load_cookies(None, [browser], None)
cookie_dict = {}
for cookie in jar:
if self._domain in cookie.domain:
cookie_dict[cookie.name] = cookie.value
return cookie_dict

def _on_web_login_succeed(self, cookies):
self.cookies_text_edit.setText(json.dumps(cookies, indent=2))
self._web_login.close()
Expand Down

0 comments on commit 3b64331

Please sign in to comment.