def fb2mlize_images(self): ''' This function uses the self.image_hrefs dictionary mapping. It is populated by the dump_text function. ''' from calibre.ebooks.oeb.base import OEB_RASTER_IMAGES images = [] for item in self.oeb_book.manifest: # Don't write the image if it's not referenced in the document's text. if item.href not in self.image_hrefs: continue if item.media_type in OEB_RASTER_IMAGES: try: if item.media_type != 'image/jpeg': imdata = save_cover_data_to(item.data, compression_quality=70) raw_data = as_base64_unicode(imdata) else: raw_data = as_base64_unicode(item.data) # Don't put the encoded image on a single line. data = '' col = 1 for char in raw_data: if col == 72: data += '\n' col = 1 col += 1 data += char images.append('<binary id="%s" content-type="image/jpeg">%s\n</binary>' % (self.image_hrefs[item.href], data)) except Exception as e: self.log.error('Error: Could not include file %s because ' '%s.' % (item.href, e)) return ''.join(images)
def fb2mlize_images(self): ''' This function uses the self.image_hrefs dictionary mapping. It is populated by the dump_text function. ''' from calibre.ebooks.oeb.base import OEB_RASTER_IMAGES images = [] for item in self.oeb_book.manifest: # Don't write the image if it's not referenced in the document's text. if item.href not in self.image_hrefs: continue if item.media_type in OEB_RASTER_IMAGES: try: if item.media_type not in ('image/jpeg', 'image/png'): imdata = save_cover_data_to(item.data, compression_quality=70) raw_data = as_base64_unicode(imdata) content_type = 'image/jpeg' else: raw_data = as_base64_unicode(item.data) content_type = item.media_type # Don't put the encoded image on a single line. step = 72 data = '\n'.join(raw_data[i:i + step] for i in range(0, len(raw_data), step)) images.append( '<binary id="%s" content-type="%s">%s</binary>' % (self.image_hrefs[item.href], content_type, data)) except Exception as e: self.log.error('Error: Could not include file %s because ' '%s.' % (item.href, e)) return '\n'.join(images)
def read_upgrade_response(self): from calibre.srv.http_request import read_headers st = monotonic() buf, idx = b'', -1 while idx == -1: data = self.socket.recv(1024) if not data: raise ValueError('Server did not respond with a valid HTTP upgrade response') buf += data if len(buf) > 4096: raise ValueError('Server responded with too much data to HTTP upgrade request') if monotonic() - st > self.timeout: raise ValueError('Timed out while waiting for server response to HTTP upgrade') idx = buf.find(b'\r\n\r\n') response, rest = buf[:idx+4], buf[idx+4:] if rest: self.read_buf.append(rest) lines = (x + b'\r\n' for x in response.split(b'\r\n')[:-1]) rl = next(lines) if rl != b'HTTP/1.1 101 Switching Protocols\r\n': raise ValueError('Server did not respond with correct switching protocols line') headers = read_headers(partial(next, lines)) key = as_base64_unicode(sha1((self.key + GUID_STR).encode('ascii')).digest()) if headers.get('Sec-WebSocket-Accept') != key: raise ValueError('Server did not respond with correct key in Sec-WebSocket-Accept: {} != {}'.format( key, headers.get('Sec-WebSocket-Accept')))
def finalize_headers(self, inheaders): upgrade = inheaders.get('Upgrade', '') key = inheaders.get('Sec-WebSocket-Key', None) conn = { x.strip().lower() for x in inheaders.get('Connection', '').split(',') } if key is None or upgrade.lower( ) != 'websocket' or 'upgrade' not in conn: return HTTPConnection.finalize_headers(self, inheaders) ver = inheaders.get('Sec-WebSocket-Version', 'Unknown') try: ver_ok = int(ver) >= 13 except Exception: ver_ok = False if not ver_ok: return self.simple_response( http_client.BAD_REQUEST, 'Unsupported WebSocket protocol version: %s' % ver) if self.method != 'GET': return self.simple_response( http_client.BAD_REQUEST, 'Invalid WebSocket method: %s' % self.method) response = HANDSHAKE_STR % as_base64_unicode( sha1((key + GUID_STR).encode('utf-8')).digest()) self.optimize_for_sending_packet() self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) self.set_state(WRITE, self.upgrade_connection_to_ws, ReadOnlyFileBuffer(response.encode('ascii')), inheaders)
def read_upgrade_response(self): from calibre.srv.http_request import read_headers st = monotonic() buf, idx = b'', -1 while idx == -1: data = self.socket.recv(1024) if not data: raise ValueError('Server did not respond with a valid HTTP upgrade response') buf += data if len(buf) > 4096: raise ValueError('Server responded with too much data to HTTP upgrade request') if monotonic() - st > self.timeout: raise ValueError('Timed out while waiting for server response to HTTP upgrade') idx = buf.find(b'\r\n\r\n') response, rest = buf[:idx+4], buf[idx+4:] if rest: self.read_buf.append(rest) lines = (x + b'\r\n' for x in response.split(b'\r\n')[:-1]) rl = next(lines) if rl != b'HTTP/1.1 101 Switching Protocols\r\n': raise ValueError('Server did not respond with correct switching protocols line') headers = read_headers(partial(next, lines)) key = as_base64_unicode(sha1(self.key + GUID_STR).digest()) if headers.get('Sec-WebSocket-Accept') != key: raise ValueError('Server did not respond with correct key in Sec-WebSocket-Accept')
def __init__(self, port, timeout=5): self.timeout = timeout self.socket = socket.create_connection(('localhost', port), timeout) set_socket_inherit(self.socket, False) self.key = as_base64_unicode(os.urandom(8)) self.socket.sendall(HANDSHAKE_STR.format(self.key).encode('ascii')) self.read_buf = deque() self.read_upgrade_response() self.mask = memoryview(os.urandom(4)) self.frames = []
def __init__(self, parent): QWebView.__init__(self, parent) self._page = Page() self._page.elem_clicked.connect(self.elem_clicked) self.setPage(self._page) raw = ''' body { background-color: white } .calibre_toc_hover:hover { cursor: pointer !important; border-top: solid 5px green !important } ''' raw = '::selection {background:#ffff00; color:#000;}\n'+raw data = 'data:text/css;charset=utf-8;base64,' data += as_base64_unicode(raw) self.settings().setUserStyleSheetUrl(QUrl(data))
def __init__(self, parent): QWebView.__init__(self, parent) self._page = Page() self._page.elem_clicked.connect(self.elem_clicked) self.setPage(self._page) raw = ''' body { background-color: white } .calibre_toc_hover:hover { cursor: pointer !important; border-top: solid 5px green !important } ''' raw = '::selection {background:#ffff00; color:#000;}\n' + raw data = 'data:text/css;charset=utf-8;base64,' data += as_base64_unicode(raw) self.settings().setUserStyleSheetUrl(QUrl(data))
def encode_thumbnail(thumbnail): ''' Encode the image part of a thumbnail, then return the 3 part tuple ''' from calibre.utils.imghdr import identify if thumbnail is None: return None if not isinstance(thumbnail, (tuple, list)): try: width, height = identify(as_bytes(thumbnail))[1:] if width < 0 or height < 0: return None thumbnail = (width, height, thumbnail) except Exception: return None return (thumbnail[0], thumbnail[1], as_base64_unicode(thumbnail[2]))
def metadata_as_dict(mi, encode_cover_data=False): if hasattr(mi, 'to_book_metadata'): mi = mi.to_book_metadata() ans = {} for field in SERIALIZABLE_FIELDS: if field != 'cover' and not mi.is_null(field): val = getattr(mi, field) ans[field] = ensure_unicode(val) if mi.cover_data and mi.cover_data[1]: if encode_cover_data: ans['cover_data'] = [mi.cover_data[0], as_base64_unicode(mi.cover_data[1])] else: ans['cover_data'] = mi.cover_data um = mi.get_all_user_metadata(False) if um: ans['user_metadata'] = um return ans
def __init__(self, parent): QWebPage.__init__(self, parent) settings = self.settings() apply_settings(settings, config().parse()) settings.setMaximumPagesInCache(0) secure_web_page(settings) settings.setAttribute(settings.PrivateBrowsingEnabled, True) settings.setAttribute(settings.LinksIncludedInFocusChain, False) settings.setAttribute(settings.DeveloperExtrasEnabled, True) settings.setDefaultTextEncoding('utf-8') data = 'data:text/css;charset=utf-8;base64,' css = '[data-in-split-mode="1"] [data-is-block="1"]:hover { cursor: pointer !important; border-top: solid 5px green !important }' data += as_base64_unicode(css) settings.setUserStyleSheetUrl(QUrl(data)) self.setNetworkAccessManager(NetworkAccessManager(self)) self.setLinkDelegationPolicy(self.DelegateAllLinks) self.mainFrame().javaScriptWindowObjectCleared.connect(self.init_javascript) self.init_javascript()
def __init__(self, parent): QWebPage.__init__(self, parent) settings = self.settings() apply_settings(settings, config().parse()) settings.setMaximumPagesInCache(0) secure_web_page(settings) settings.setAttribute(settings.PrivateBrowsingEnabled, True) settings.setAttribute(settings.LinksIncludedInFocusChain, False) settings.setAttribute(settings.DeveloperExtrasEnabled, True) settings.setDefaultTextEncoding('utf-8') data = 'data:text/css;charset=utf-8;base64,' css = '[data-in-split-mode="1"] [data-is-block="1"]:hover { cursor: pointer !important; border-top: solid 5px green !important }' data += as_base64_unicode(css) settings.setUserStyleSheetUrl(QUrl(data)) self.setNetworkAccessManager(NetworkAccessManager(self)) self.setLinkDelegationPolicy(self.DelegateAllLinks) self.mainFrame().javaScriptWindowObjectCleared.connect( self.init_javascript) self.init_javascript()
def finalize_headers(self, inheaders): upgrade = inheaders.get('Upgrade', '') key = inheaders.get('Sec-WebSocket-Key', None) conn = {x.strip().lower() for x in inheaders.get('Connection', '').split(',')} if key is None or upgrade.lower() != 'websocket' or 'upgrade' not in conn: return HTTPConnection.finalize_headers(self, inheaders) ver = inheaders.get('Sec-WebSocket-Version', 'Unknown') try: ver_ok = int(ver) >= 13 except Exception: ver_ok = False if not ver_ok: return self.simple_response(http_client.BAD_REQUEST, 'Unsupported WebSocket protocol version: %s' % ver) if self.method != 'GET': return self.simple_response(http_client.BAD_REQUEST, 'Invalid WebSocket method: %s' % self.method) response = HANDSHAKE_STR % as_base64_unicode(sha1((key + GUID_STR).encode('utf-8')).digest()) self.optimize_for_sending_packet() self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) self.set_state(WRITE, self.upgrade_connection_to_ws, ReadOnlyFileBuffer(response.encode('ascii')), inheaders)
def _encode_into_jpeg(data): data = save_cover_data_to(data) return as_base64_unicode(data)
def __init__(self, ebook, orig, is_scrambled, fmap, parent=None): QDialog.__init__(self, parent=parent) self.setWindowFlags(Qt.Window) self.orig = orig self.ebook = ebook self.revfmap = {v: k for (k, v) in iteritems(fmap)} # create widgets lay = QVBoxLayout() self.setLayout(lay) buttonBox = QDialogButtonBox(QDialogButtonBox.Close) self.webview_orig = Webview() self.webview_scram = Webview() settings = self.webview_orig.settings() if hasattr(settings, 'setUserStyleSheetUrl'): # QWebView from QtWebKit style = 'body {%s}' % CSSBG cssurl = 'data:text/css;charset=utf-8;base64,' cssurl += as_base64_unicode(style) self.webview_orig.settings().setUserStyleSheetUrl(QUrl(cssurl)) self.webview_scram.settings().setUserStyleSheetUrl(QUrl(cssurl)) elif hasattr(self.webview_orig, 'setStyleSheet'): # QWebEngineView from QtWebEngine # setStyleSheet doesn't seem to work at the moment self.webview_orig.setStyleSheet('Webview {%s}' % CSSBG) self.webview_scram.setStyleSheet('Webview {%s}' % CSSBG) dummytext = '<body><p>*** Text content could not be displayed ...</p></body>' self.webview_orig.setHtml(dummytext) self.webview_scram.setHtml(dummytext) self.htmlList_orig = QListWidget() self.htmlList_scram = QListWidget() self.htmlList_orig.setMinimumWidth(300) self.htmlList_scram.setMinimumWidth(300) gpbox1 = QGroupBox() lay1 = QHBoxLayout() gpbox1.setLayout(lay1) lay1.addWidget(self.htmlList_orig) gpbox3 = QGroupBox() lay3 = QHBoxLayout() gpbox3.setLayout(lay3) lay3.addWidget(self.htmlList_scram) gpbox2 = QGroupBox('Original text content:') lay2 = QHBoxLayout() gpbox2.setLayout(lay2) lay2.addWidget(self.webview_orig) gpbox4 = QGroupBox('Original text content:') lay4 = QHBoxLayout() gpbox4.setLayout(lay4) lay4.addWidget(self.webview_scram) splitter = QSplitter(Qt.Horizontal) splitter.addWidget(gpbox1) splitter.addWidget(gpbox2) splitter.addWidget(gpbox3) splitter.addWidget(gpbox4) lay.addWidget(splitter) lay.addWidget(buttonBox) # create connect signals/slots buttonBox.rejected.connect(self.reject) self.htmlList_scram.currentRowChanged.connect( self.htmlList_currentRowChanged) self.htmlList_scram.itemDoubleClicked.connect( self.htmlList_itemDoubleClicked) self.htmlList_orig.setEnabled(False) self.htmlnames_scram = get_textnames(self.ebook) self.htmlnames_orig = tuple( [self.revfmap.get(an, an) for an in self.htmlnames_scram]) gpbox1.setTitle('Original HTML files: %s' % len(self.htmlnames_orig)) gpbox3.setTitle('Original HTML files: %s' % len(self.htmlnames_scram)) self.htmlList_orig.clear() self.htmlList_orig.addItems(self.htmlnames_orig) self.htmlList_scram.clear() self.htmlList_scram.addItems(self.htmlnames_scram) if not self.revfmap: gpbox1.setVisible(False) msg = '%s Preview: Original' % CAPTION if not is_scrambled: self.setWindowTitle(msg) gpbox1.setVisible(False) gpbox2.setVisible(False) else: self.setWindowTitle(msg + ' vs. Scrambled') gpbox3.setTitle('Scrambled HTML files: %s' % len(self.htmlnames_scram)) gpbox4.setTitle('Scrambled text content:') self.htmlList_scram.setCurrentRow(0)