mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
...
This commit is contained in:
parent
c2feceffb0
commit
72a5e1d5c0
@ -13,7 +13,7 @@ from cookielib import Cookie
|
||||
from PyQt4.Qt import (QObject, QNetworkAccessManager, QNetworkDiskCache,
|
||||
QNetworkProxy, QNetworkProxyFactory, QEventLoop, QUrl,
|
||||
QDialog, QVBoxLayout, QSize, QNetworkCookieJar)
|
||||
from PyQt4.QtWebKit import QWebPage, QWebSettings, QWebView
|
||||
from PyQt4.QtWebKit import QWebPage, QWebSettings, QWebView, QWebElement
|
||||
|
||||
from calibre import USER_AGENT, prints, get_proxies, get_proxy_info
|
||||
from calibre.constants import ispy3, config_dir
|
||||
@ -296,11 +296,6 @@ class Browser(QObject, FormsMixin):
|
||||
log.filter_level = log.DEBUG
|
||||
self.log = log
|
||||
|
||||
self.jquery_lib = P('content_server/jquery.js', data=True,
|
||||
allow_user_override=False).decode('utf-8')
|
||||
self.simulate_lib = P('jquery.simulate.js', data=True,
|
||||
allow_user_override=False).decode('utf-8')
|
||||
|
||||
self.page = WebPage(log, confirm_callback=confirm_callback,
|
||||
prompt_callback=prompt_callback, user_agent=user_agent,
|
||||
enable_developer_tools=enable_developer_tools,
|
||||
@ -333,6 +328,13 @@ class Browser(QObject, FormsMixin):
|
||||
raise Timeout('Waiting for replies took longer than %d seconds' %
|
||||
timeout)
|
||||
|
||||
def run_for_a_time(self, timeout):
|
||||
final_time = time.time() + timeout
|
||||
loop = QEventLoop(self)
|
||||
while (time.time() < final_time):
|
||||
if not loop.processEvents():
|
||||
time.sleep(0.1)
|
||||
|
||||
def visit(self, url, timeout=30.0):
|
||||
'''
|
||||
Open the page specified in URL and wait for it to complete loading.
|
||||
@ -347,9 +349,9 @@ class Browser(QObject, FormsMixin):
|
||||
self.page.mainFrame().load(QUrl(url))
|
||||
return self._wait_for_load(timeout, url)
|
||||
|
||||
def click(self, qwe, wait_for_load=True, ajax_replies=0, timeout=30.0):
|
||||
def click(self, qwe_or_selector, wait_for_load=True, ajax_replies=0, timeout=30.0):
|
||||
'''
|
||||
Click the QWebElement pointed to by qwe.
|
||||
Click the :class:`QWebElement` pointed to by qwe_or_selector.
|
||||
|
||||
:param wait_for_load: If you know that the click is going to cause a
|
||||
new page to be loaded, set this to True to have
|
||||
@ -358,6 +360,12 @@ class Browser(QObject, FormsMixin):
|
||||
that triggers some AJAX interaction
|
||||
'''
|
||||
initial_count = self.nam.reply_count
|
||||
qwe = qwe_or_selector
|
||||
if not isinstance(qwe, QWebElement):
|
||||
qwe = self.page.mainFrame().findFirstElement(qwe)
|
||||
if qwe.isNull():
|
||||
raise ValueError('Failed to find element with selector: %r'
|
||||
% qwe_or_selector)
|
||||
js = '''
|
||||
var e = document.createEvent('MouseEvents');
|
||||
e.initEvent( 'click', true, true );
|
||||
@ -370,6 +378,24 @@ class Browser(QObject, FormsMixin):
|
||||
elif wait_for_load and not self._wait_for_load(timeout):
|
||||
raise LoadError('Clicking resulted in a failed load')
|
||||
|
||||
def click_text_link(self, text_or_regex, selector='a[href]',
|
||||
wait_for_load=True, ajax_replies=0, timeout=30.0):
|
||||
target = None
|
||||
for qwe in self.page.mainFrame().findAllElements(selector):
|
||||
src = unicode(qwe.toPlainText())
|
||||
if hasattr(text_or_regex, 'match') and text_or_regex.search(src):
|
||||
target = qwe
|
||||
break
|
||||
if src.lower() == text_or_regex.lower():
|
||||
target = qwe
|
||||
break
|
||||
if target is None:
|
||||
raise ValueError('No element matching %r with text %s found'%(
|
||||
selector, text_or_regex))
|
||||
return self.click(target, wait_for_load=wait_for_load,
|
||||
ajax_replies=ajax_replies, timeout=timeout)
|
||||
|
||||
|
||||
def show_browser(self):
|
||||
'''
|
||||
Show the currently loaded web page in a window. Useful for debugging.
|
||||
@ -377,6 +403,7 @@ class Browser(QObject, FormsMixin):
|
||||
view = BrowserView(self.page)
|
||||
view.exec_()
|
||||
|
||||
@property
|
||||
def cookies(self):
|
||||
'''
|
||||
Return all the cookies set currently as :class:`Cookie` objects.
|
||||
@ -384,4 +411,14 @@ class Browser(QObject, FormsMixin):
|
||||
'''
|
||||
return list(self.nam.py_cookies())
|
||||
|
||||
@property
|
||||
def html(self):
|
||||
return unicode(self.page.mainFrame().toHtml())
|
||||
|
||||
def close(self):
|
||||
try:
|
||||
self.visit('about:blank', timeout=0.01)
|
||||
except Timeout:
|
||||
pass
|
||||
self.nam = self.page = None
|
||||
|
||||
|
56
src/calibre/web/jsbrowser/login.py
Normal file
56
src/calibre/web/jsbrowser/login.py
Normal file
@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||
from __future__ import (unicode_literals, division, absolute_import,
|
||||
print_function)
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
from calibre import USER_AGENT
|
||||
from calibre.web.jsbrowser.browser import Browser
|
||||
|
||||
def do_login(login_url, calibre_browser, form_selector, controls={},
|
||||
num_of_replies=0, timeout=60.0, verbosity=0, pause_time=5,
|
||||
post_visit_callback=None, post_submit_callback=None,
|
||||
submit_control_selector=None):
|
||||
ua = USER_AGENT
|
||||
for key, val in calibre_browser.addheaders:
|
||||
if key.lower() == 'user-agent':
|
||||
ua = val
|
||||
break
|
||||
br = Browser(user_agent=ua, verbosity=verbosity)
|
||||
if not br.visit(login_url, timeout=timeout):
|
||||
raise ValueError('Failed to load the login URL: %r'%login_url)
|
||||
|
||||
if callable(post_visit_callback):
|
||||
post_visit_callback(br)
|
||||
|
||||
f = br.select_form(form_selector)
|
||||
for key, val in controls.iteritems():
|
||||
f[key] = val
|
||||
|
||||
# br.show_browser()
|
||||
|
||||
if num_of_replies > 0:
|
||||
br.ajax_submit(num_of_replies=num_of_replies, timeout=timeout,
|
||||
submit_control_selector=submit_control_selector)
|
||||
else:
|
||||
br.submit(timeout=timeout,
|
||||
submit_control_selector=submit_control_selector)
|
||||
|
||||
# Give any javascript some time to run
|
||||
br.run_for_a_time(pause_time)
|
||||
|
||||
if callable(post_submit_callback):
|
||||
post_submit_callback(br)
|
||||
|
||||
br.show_browser()
|
||||
|
||||
cj = calibre_browser.cookiejar
|
||||
for cookie in br.cookies:
|
||||
cj.set_cookie(cookie)
|
||||
html = br.html
|
||||
br.close()
|
||||
return html
|
||||
|
@ -185,7 +185,7 @@ class Test(unittest.TestCase):
|
||||
self.assertEqual(self.browser.visit('http://127.0.0.1:%d/cookies'%self.port),
|
||||
True)
|
||||
sent_cookies = self.server.sent_cookies
|
||||
cookies = self.browser.cookies()
|
||||
cookies = self.browser.cookies
|
||||
cmap = {c.name:c for c in cookies}
|
||||
for name, vals in sent_cookies.iteritems():
|
||||
c = cmap[name]
|
||||
|
Loading…
x
Reference in New Issue
Block a user