mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -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,
|
from PyQt4.Qt import (QObject, QNetworkAccessManager, QNetworkDiskCache,
|
||||||
QNetworkProxy, QNetworkProxyFactory, QEventLoop, QUrl,
|
QNetworkProxy, QNetworkProxyFactory, QEventLoop, QUrl,
|
||||||
QDialog, QVBoxLayout, QSize, QNetworkCookieJar)
|
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 import USER_AGENT, prints, get_proxies, get_proxy_info
|
||||||
from calibre.constants import ispy3, config_dir
|
from calibre.constants import ispy3, config_dir
|
||||||
@ -296,11 +296,6 @@ class Browser(QObject, FormsMixin):
|
|||||||
log.filter_level = log.DEBUG
|
log.filter_level = log.DEBUG
|
||||||
self.log = log
|
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,
|
self.page = WebPage(log, confirm_callback=confirm_callback,
|
||||||
prompt_callback=prompt_callback, user_agent=user_agent,
|
prompt_callback=prompt_callback, user_agent=user_agent,
|
||||||
enable_developer_tools=enable_developer_tools,
|
enable_developer_tools=enable_developer_tools,
|
||||||
@ -333,6 +328,13 @@ class Browser(QObject, FormsMixin):
|
|||||||
raise Timeout('Waiting for replies took longer than %d seconds' %
|
raise Timeout('Waiting for replies took longer than %d seconds' %
|
||||||
timeout)
|
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):
|
def visit(self, url, timeout=30.0):
|
||||||
'''
|
'''
|
||||||
Open the page specified in URL and wait for it to complete loading.
|
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))
|
self.page.mainFrame().load(QUrl(url))
|
||||||
return self._wait_for_load(timeout, 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
|
: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
|
new page to be loaded, set this to True to have
|
||||||
@ -358,6 +360,12 @@ class Browser(QObject, FormsMixin):
|
|||||||
that triggers some AJAX interaction
|
that triggers some AJAX interaction
|
||||||
'''
|
'''
|
||||||
initial_count = self.nam.reply_count
|
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 = '''
|
js = '''
|
||||||
var e = document.createEvent('MouseEvents');
|
var e = document.createEvent('MouseEvents');
|
||||||
e.initEvent( 'click', true, true );
|
e.initEvent( 'click', true, true );
|
||||||
@ -370,6 +378,24 @@ class Browser(QObject, FormsMixin):
|
|||||||
elif wait_for_load and not self._wait_for_load(timeout):
|
elif wait_for_load and not self._wait_for_load(timeout):
|
||||||
raise LoadError('Clicking resulted in a failed load')
|
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):
|
def show_browser(self):
|
||||||
'''
|
'''
|
||||||
Show the currently loaded web page in a window. Useful for debugging.
|
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 = BrowserView(self.page)
|
||||||
view.exec_()
|
view.exec_()
|
||||||
|
|
||||||
|
@property
|
||||||
def cookies(self):
|
def cookies(self):
|
||||||
'''
|
'''
|
||||||
Return all the cookies set currently as :class:`Cookie` objects.
|
Return all the cookies set currently as :class:`Cookie` objects.
|
||||||
@ -384,4 +411,14 @@ class Browser(QObject, FormsMixin):
|
|||||||
'''
|
'''
|
||||||
return list(self.nam.py_cookies())
|
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),
|
self.assertEqual(self.browser.visit('http://127.0.0.1:%d/cookies'%self.port),
|
||||||
True)
|
True)
|
||||||
sent_cookies = self.server.sent_cookies
|
sent_cookies = self.server.sent_cookies
|
||||||
cookies = self.browser.cookies()
|
cookies = self.browser.cookies
|
||||||
cmap = {c.name:c for c in cookies}
|
cmap = {c.name:c for c in cookies}
|
||||||
for name, vals in sent_cookies.iteritems():
|
for name, vals in sent_cookies.iteritems():
|
||||||
c = cmap[name]
|
c = cmap[name]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user