mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
py3: port use as base64 module
This commit is contained in:
parent
a0afe775ba
commit
fcd5700306
@ -6,7 +6,6 @@ __copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
|||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
import os, time
|
import os, time
|
||||||
from base64 import b64decode
|
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
|
||||||
from calibre import prints, guess_type, isbytestring, fsync
|
from calibre import prints, guess_type, isbytestring, fsync
|
||||||
@ -16,6 +15,7 @@ from calibre.constants import DEBUG, preferred_encoding
|
|||||||
from calibre.ebooks.chardet import xml_to_unicode
|
from calibre.ebooks.chardet import xml_to_unicode
|
||||||
from calibre.ebooks.metadata import authors_to_string, title_sort, \
|
from calibre.ebooks.metadata import authors_to_string, title_sort, \
|
||||||
authors_to_sort_string
|
authors_to_sort_string
|
||||||
|
from polyglot.binary import from_base64_bytes
|
||||||
|
|
||||||
'''
|
'''
|
||||||
cahceExt.xml
|
cahceExt.xml
|
||||||
@ -380,8 +380,8 @@ class XMLCache(object):
|
|||||||
'descendant::*[local-name()="png"]'):
|
'descendant::*[local-name()="png"]'):
|
||||||
if img.text:
|
if img.text:
|
||||||
try:
|
try:
|
||||||
raw = b64decode(img.text.strip())
|
raw = from_base64_bytes(img.text.strip())
|
||||||
except:
|
except Exception:
|
||||||
continue
|
continue
|
||||||
book.thumbnail = raw
|
book.thumbnail = raw
|
||||||
break
|
break
|
||||||
|
@ -10,12 +10,12 @@ __docformat__ = 'restructuredtext en'
|
|||||||
|
|
||||||
def base64_decode(raw):
|
def base64_decode(raw):
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from base64 import b64decode
|
from polyglot.binary import from_base64_bytes
|
||||||
|
|
||||||
# First try the python implementation as it is faster
|
# First try the python implementation as it is faster
|
||||||
try:
|
try:
|
||||||
return b64decode(raw)
|
return from_base64_bytes(raw)
|
||||||
except TypeError:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Try a more robust version (adapted from FBReader sources)
|
# Try a more robust version (adapted from FBReader sources)
|
||||||
@ -49,5 +49,3 @@ def base64_decode(raw):
|
|||||||
tot >>= 8
|
tot >>= 8
|
||||||
out.write(bytes(triple))
|
out.write(bytes(triple))
|
||||||
return out.getvalue()
|
return out.getvalue()
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ Transform OEB content into FB2 markup
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
import re, textwrap, uuid
|
import re, textwrap, uuid
|
||||||
from base64 import b64encode
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
@ -20,6 +19,7 @@ from calibre.utils.localization import lang_as_iso639_1
|
|||||||
from calibre.utils.img import save_cover_data_to
|
from calibre.utils.img import save_cover_data_to
|
||||||
from calibre.ebooks.oeb.base import urlnormalize
|
from calibre.ebooks.oeb.base import urlnormalize
|
||||||
from polyglot.builtins import unicode_type, string_or_bytes
|
from polyglot.builtins import unicode_type, string_or_bytes
|
||||||
|
from polyglot.binary import as_base64_unicode
|
||||||
|
|
||||||
|
|
||||||
class FB2MLizer(object):
|
class FB2MLizer(object):
|
||||||
@ -308,9 +308,9 @@ class FB2MLizer(object):
|
|||||||
try:
|
try:
|
||||||
if item.media_type != 'image/jpeg':
|
if item.media_type != 'image/jpeg':
|
||||||
imdata = save_cover_data_to(item.data, compression_quality=70)
|
imdata = save_cover_data_to(item.data, compression_quality=70)
|
||||||
raw_data = b64encode(imdata)
|
raw_data = as_base64_unicode(imdata)
|
||||||
else:
|
else:
|
||||||
raw_data = b64encode(item.data)
|
raw_data = as_base64_unicode(item.data)
|
||||||
# Don't put the encoded image on a single line.
|
# Don't put the encoded image on a single line.
|
||||||
data = ''
|
data = ''
|
||||||
col = 1
|
col = 1
|
||||||
|
@ -5,7 +5,6 @@ Created on 4 Jun 2010
|
|||||||
'''
|
'''
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
from base64 import b64encode, b64decode
|
|
||||||
import json, traceback
|
import json, traceback
|
||||||
from datetime import datetime, time
|
from datetime import datetime, time
|
||||||
|
|
||||||
@ -14,6 +13,7 @@ from calibre.constants import filesystem_encoding, preferred_encoding
|
|||||||
from calibre.library.field_metadata import FieldMetadata
|
from calibre.library.field_metadata import FieldMetadata
|
||||||
from calibre import isbytestring
|
from calibre import isbytestring
|
||||||
from polyglot.builtins import iteritems, itervalues
|
from polyglot.builtins import iteritems, itervalues
|
||||||
|
from polyglot.binary import as_base64_unicode, from_base64_bytes
|
||||||
|
|
||||||
# Translate datetimes to and from strings. The string form is the datetime in
|
# Translate datetimes to and from strings. The string form is the datetime in
|
||||||
# UTC. The returned date is also UTC
|
# UTC. The returned date is also UTC
|
||||||
@ -57,7 +57,7 @@ def encode_thumbnail(thumbnail):
|
|||||||
thumbnail = (width, height, thumbnail)
|
thumbnail = (width, height, thumbnail)
|
||||||
except Exception:
|
except Exception:
|
||||||
return None
|
return None
|
||||||
return (thumbnail[0], thumbnail[1], b64encode(str(thumbnail[2])))
|
return (thumbnail[0], thumbnail[1], as_base64_unicode(thumbnail[2]))
|
||||||
|
|
||||||
|
|
||||||
def decode_thumbnail(tup):
|
def decode_thumbnail(tup):
|
||||||
@ -66,7 +66,7 @@ def decode_thumbnail(tup):
|
|||||||
'''
|
'''
|
||||||
if tup is None:
|
if tup is None:
|
||||||
return None
|
return None
|
||||||
return (tup[0], tup[1], b64decode(tup[2]))
|
return (tup[0], tup[1], from_base64_bytes(tup[2]))
|
||||||
|
|
||||||
|
|
||||||
def object_to_unicode(obj, enc=preferred_encoding):
|
def object_to_unicode(obj, enc=preferred_encoding):
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
|
|
||||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
import base64
|
|
||||||
|
|
||||||
from calibre.constants import preferred_encoding
|
from calibre.constants import preferred_encoding
|
||||||
from calibre.ebooks.metadata.book import SERIALIZABLE_FIELDS
|
from calibre.ebooks.metadata.book import SERIALIZABLE_FIELDS
|
||||||
from calibre.ebooks.metadata.book.base import Metadata
|
from calibre.ebooks.metadata.book.base import Metadata
|
||||||
from calibre.utils.imghdr import what
|
from calibre.utils.imghdr import what
|
||||||
from polyglot.builtins import iteritems, unicode_type
|
from polyglot.builtins import iteritems, unicode_type
|
||||||
|
from polyglot.binary import as_base64_unicode
|
||||||
|
|
||||||
|
|
||||||
def ensure_unicode(obj, enc=preferred_encoding):
|
def ensure_unicode(obj, enc=preferred_encoding):
|
||||||
@ -52,7 +52,7 @@ def metadata_as_dict(mi, encode_cover_data=False):
|
|||||||
ans[field] = ensure_unicode(val)
|
ans[field] = ensure_unicode(val)
|
||||||
if mi.cover_data and mi.cover_data[1]:
|
if mi.cover_data and mi.cover_data[1]:
|
||||||
if encode_cover_data:
|
if encode_cover_data:
|
||||||
ans['cover_data'] = [mi.cover_data[0], base64.standard_b64encode(bytes(mi.cover_data[1]))]
|
ans['cover_data'] = [mi.cover_data[0], as_base64_unicode(mi.cover_data[1])]
|
||||||
else:
|
else:
|
||||||
ans['cover_data'] = mi.cover_data
|
ans['cover_data'] = mi.cover_data
|
||||||
um = mi.get_all_user_metadata(False)
|
um = mi.get_all_user_metadata(False)
|
||||||
|
@ -8,7 +8,6 @@ __copyright__ = '2011, Roman Mukhin <ramses_ru at hotmail.com>, '\
|
|||||||
import os, random
|
import os, random
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from string import ascii_letters, digits
|
from string import ascii_letters, digits
|
||||||
from base64 import b64encode
|
|
||||||
|
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
|
||||||
@ -19,6 +18,7 @@ from calibre import guess_type, guess_all_extensions, prints, force_unicode
|
|||||||
from calibre.ebooks.metadata import MetaInformation, check_isbn
|
from calibre.ebooks.metadata import MetaInformation, check_isbn
|
||||||
from calibre.ebooks.chardet import xml_to_unicode
|
from calibre.ebooks.chardet import xml_to_unicode
|
||||||
from polyglot.builtins import unicode_type
|
from polyglot.builtins import unicode_type
|
||||||
|
from polyglot.binary import as_base64_unicode
|
||||||
|
|
||||||
|
|
||||||
NAMESPACES = {
|
NAMESPACES = {
|
||||||
@ -383,7 +383,7 @@ def _rnd_pic_file_name(prefix='calibre_cover_', size=32, ext='jpg'):
|
|||||||
|
|
||||||
def _encode_into_jpeg(data):
|
def _encode_into_jpeg(data):
|
||||||
data = save_cover_data_to(data)
|
data = save_cover_data_to(data)
|
||||||
return b64encode(data)
|
return as_base64_unicode(data)
|
||||||
|
|
||||||
|
|
||||||
def _set_cover(title_info, mi, ctx):
|
def _set_cover(title_info, mi, ctx):
|
||||||
|
@ -8,7 +8,7 @@ from __future__ import (unicode_literals, division, absolute_import,
|
|||||||
# Based on work of John Howell reversing the KFX format
|
# Based on work of John Howell reversing the KFX format
|
||||||
# https://www.mobileread.com/forums/showpost.php?p=3176029&postcount=89
|
# https://www.mobileread.com/forums/showpost.php?p=3176029&postcount=89
|
||||||
|
|
||||||
import struct, sys, base64, re
|
import struct, sys, re
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from calibre.ebooks.metadata.book.base import Metadata
|
from calibre.ebooks.metadata.book.base import Metadata
|
||||||
@ -19,6 +19,7 @@ from calibre.utils.date import parse_only_date
|
|||||||
from calibre.utils.localization import canonicalize_lang
|
from calibre.utils.localization import canonicalize_lang
|
||||||
from calibre.utils.imghdr import identify
|
from calibre.utils.imghdr import identify
|
||||||
from polyglot.builtins import unicode_type
|
from polyglot.builtins import unicode_type
|
||||||
|
from polyglot.binary import as_base64_bytes, from_base64_bytes
|
||||||
|
|
||||||
|
|
||||||
class InvalidKFX(ValueError):
|
class InvalidKFX(ValueError):
|
||||||
@ -155,7 +156,7 @@ class Entity(PackedBlock):
|
|||||||
if PackedData(self.entity_data).unpack_one('4s') == ION_MAGIC:
|
if PackedData(self.entity_data).unpack_one('4s') == ION_MAGIC:
|
||||||
entity_value = PackedIon(self.entity_data).decode()
|
entity_value = PackedIon(self.entity_data).decode()
|
||||||
else:
|
else:
|
||||||
entity_value = base64.b64encode(self.entity_data)
|
entity_value = as_base64_bytes(self.entity_data)
|
||||||
|
|
||||||
return (property_name(self.entity_type), property_name(self.entity_id), entity_value)
|
return (property_name(self.entity_type), property_name(self.entity_id), entity_value)
|
||||||
|
|
||||||
@ -343,8 +344,8 @@ def read_metadata_kfx(stream, read_cover=True):
|
|||||||
mi.publisher = get('publisher')
|
mi.publisher = get('publisher')
|
||||||
if read_cover and m[COVER_KEY]:
|
if read_cover and m[COVER_KEY]:
|
||||||
try:
|
try:
|
||||||
data = base64.standard_b64decode(m[COVER_KEY])
|
data = from_base64_bytes(m[COVER_KEY])
|
||||||
fmt, w, h = identify(bytes(data))
|
fmt, w, h = identify(data)
|
||||||
except Exception:
|
except Exception:
|
||||||
w, h, fmt = 0, 0, None
|
w, h, fmt = 0, 0, None
|
||||||
if fmt and w > -1 and h > -1:
|
if fmt and w > -1 and h > -1:
|
||||||
|
@ -10,7 +10,6 @@ import os
|
|||||||
import posixpath
|
import posixpath
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
from base64 import standard_b64decode
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from contextlib import closing
|
from contextlib import closing
|
||||||
from functools import partial
|
from functools import partial
|
||||||
@ -25,6 +24,7 @@ from calibre.ptempfile import TemporaryDirectory
|
|||||||
from calibre.web import get_download_filename_from_response
|
from calibre.web import get_download_filename_from_response
|
||||||
from polyglot.builtins import iteritems
|
from polyglot.builtins import iteritems
|
||||||
from polyglot.urllib import urlopen, urlparse
|
from polyglot.urllib import urlopen, urlparse
|
||||||
|
from polyglot.binary import from_base64_bytes
|
||||||
|
|
||||||
|
|
||||||
def is_external(url):
|
def is_external(url):
|
||||||
@ -117,7 +117,7 @@ def download_one(tdir, timeout, progress_report, data_uri_map, url):
|
|||||||
parts = prefix.split(';')
|
parts = prefix.split(';')
|
||||||
if parts and parts[-1].lower() == 'base64':
|
if parts and parts[-1].lower() == 'base64':
|
||||||
payload = re.sub(r'\s+', '', payload)
|
payload = re.sub(r'\s+', '', payload)
|
||||||
payload = standard_b64decode(payload)
|
payload = from_base64_bytes(payload)
|
||||||
else:
|
else:
|
||||||
payload = payload.encode('utf-8')
|
payload = payload.encode('utf-8')
|
||||||
seen_before = data_uri_map.get(payload)
|
seen_before = data_uri_map.get(payload)
|
||||||
|
@ -28,9 +28,9 @@ class DataURL(object):
|
|||||||
continue
|
continue
|
||||||
if ';base64' in header:
|
if ';base64' in header:
|
||||||
data = re.sub(r'\s+', '', data)
|
data = re.sub(r'\s+', '', data)
|
||||||
from base64 import b64decode
|
from polyglot.binary import from_base64_bytes
|
||||||
try:
|
try:
|
||||||
data = b64decode(data)
|
data = from_base64_bytes(data)
|
||||||
except Exception:
|
except Exception:
|
||||||
self.log.error('Found invalid base64 encoded data URI, ignoring it')
|
self.log.error('Found invalid base64 encoded data URI, ignoring it')
|
||||||
continue
|
continue
|
||||||
|
@ -6,7 +6,7 @@ __license__ = 'GPL 3'
|
|||||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
import traceback, base64
|
import traceback
|
||||||
from contextlib import closing
|
from contextlib import closing
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
@ -15,6 +15,7 @@ from calibre.constants import DEBUG
|
|||||||
from calibre.utils.img import scale_image
|
from calibre.utils.img import scale_image
|
||||||
from polyglot.builtins import range
|
from polyglot.builtins import range
|
||||||
from polyglot.queue import Queue
|
from polyglot.queue import Queue
|
||||||
|
from polyglot.binary import from_base64_bytes
|
||||||
|
|
||||||
|
|
||||||
class GenericDownloadThreadPool(object):
|
class GenericDownloadThreadPool(object):
|
||||||
@ -143,7 +144,7 @@ class CoverThreadPool(GenericDownloadThreadPool):
|
|||||||
|
|
||||||
|
|
||||||
def decode_data_url(url):
|
def decode_data_url(url):
|
||||||
return base64.standard_b64decode(url.partition(',')[2])
|
return from_base64_bytes(url.partition(',')[2])
|
||||||
|
|
||||||
|
|
||||||
class CoverThread(Thread):
|
class CoverThread(Thread):
|
||||||
|
@ -24,6 +24,15 @@ from calibre.gui2.store.search_result import SearchResult
|
|||||||
from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||||
|
|
||||||
|
|
||||||
|
def as_base64(data):
|
||||||
|
if not isinstance(data, bytes):
|
||||||
|
data = data.encode('utf-8')
|
||||||
|
ans = b64encode(data)
|
||||||
|
if isinstance(ans, bytes):
|
||||||
|
ans = ans.decode('ascii')
|
||||||
|
return ans
|
||||||
|
|
||||||
|
|
||||||
class EbookpointStore(BasicStoreConfig, StorePlugin):
|
class EbookpointStore(BasicStoreConfig, StorePlugin):
|
||||||
|
|
||||||
def open(self, parent=None, detail_item=None, external=False):
|
def open(self, parent=None, detail_item=None, external=False):
|
||||||
@ -31,11 +40,11 @@ class EbookpointStore(BasicStoreConfig, StorePlugin):
|
|||||||
|
|
||||||
url = 'http://ebookpoint.pl/'
|
url = 'http://ebookpoint.pl/'
|
||||||
|
|
||||||
aff_url = aff_root + str(b64encode(url))
|
aff_url = aff_root + as_base64(url)
|
||||||
|
|
||||||
detail_url = None
|
detail_url = None
|
||||||
if detail_item:
|
if detail_item:
|
||||||
detail_url = aff_root + str(b64encode(detail_item))
|
detail_url = aff_root + as_base64(detail_item)
|
||||||
|
|
||||||
if external or self.config.get('open_external', False):
|
if external or self.config.get('open_external', False):
|
||||||
open_url(QUrl(url_slash_cleaner(detail_url if detail_url else aff_url)))
|
open_url(QUrl(url_slash_cleaner(detail_url if detail_url else aff_url)))
|
||||||
|
@ -24,6 +24,15 @@ from calibre.gui2.store.search_result import SearchResult
|
|||||||
from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||||
|
|
||||||
|
|
||||||
|
def as_base64(data):
|
||||||
|
if not isinstance(data, bytes):
|
||||||
|
data = data.encode('utf-8')
|
||||||
|
ans = b64encode(data)
|
||||||
|
if isinstance(ans, bytes):
|
||||||
|
ans = ans.decode('ascii')
|
||||||
|
return ans
|
||||||
|
|
||||||
|
|
||||||
class EmpikStore(BasicStoreConfig, StorePlugin):
|
class EmpikStore(BasicStoreConfig, StorePlugin):
|
||||||
|
|
||||||
def open(self, parent=None, detail_item=None, external=False):
|
def open(self, parent=None, detail_item=None, external=False):
|
||||||
@ -31,11 +40,11 @@ class EmpikStore(BasicStoreConfig, StorePlugin):
|
|||||||
|
|
||||||
url = 'http://www.empik.com/ebooki'
|
url = 'http://www.empik.com/ebooki'
|
||||||
|
|
||||||
aff_url = aff_root + str(b64encode(url))
|
aff_url = aff_root + as_base64(url)
|
||||||
|
|
||||||
detail_url = None
|
detail_url = None
|
||||||
if detail_item:
|
if detail_item:
|
||||||
detail_url = aff_root + str(b64encode(detail_item))
|
detail_url = aff_root + as_base64(detail_item)
|
||||||
|
|
||||||
if external or self.config.get('open_external', False):
|
if external or self.config.get('open_external', False):
|
||||||
open_url(QUrl(url_slash_cleaner(detail_url if detail_url else aff_url)))
|
open_url(QUrl(url_slash_cleaner(detail_url if detail_url else aff_url)))
|
||||||
@ -82,4 +91,3 @@ class EmpikStore(BasicStoreConfig, StorePlugin):
|
|||||||
s.formats = formats.upper().strip()
|
s.formats = formats.upper().strip()
|
||||||
|
|
||||||
yield s
|
yield s
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ def search(query, max_results=10, timeout=60, write_raw_to=None):
|
|||||||
# We could use the <link rel="alternate" type="text/html" ...> tag from the
|
# We could use the <link rel="alternate" type="text/html" ...> tag from the
|
||||||
# detail odps page but this is easier.
|
# detail odps page but this is easier.
|
||||||
id = fix_url(''.join(data.xpath('./*[local-name() = "id"]/text()')).strip())
|
id = fix_url(''.join(data.xpath('./*[local-name() = "id"]/text()')).strip())
|
||||||
s.detail_item = url_slash_cleaner('%s/ebooks/%s' % (web_url, re.sub('[^\d]', '', id)))
|
s.detail_item = url_slash_cleaner('%s/ebooks/%s' % (web_url, re.sub(r'[^\d]', '', id)))
|
||||||
s.title = ' '.join(data.xpath('./*[local-name() = "title"]//text()')).strip()
|
s.title = ' '.join(data.xpath('./*[local-name() = "title"]//text()')).strip()
|
||||||
s.author = ', '.join(data.xpath('./*[local-name() = "content"]//text()')).strip()
|
s.author = ', '.join(data.xpath('./*[local-name() = "content"]//text()')).strip()
|
||||||
if not s.title or not s.author:
|
if not s.title or not s.author:
|
||||||
@ -83,7 +83,10 @@ def search(query, max_results=10, timeout=60, write_raw_to=None):
|
|||||||
href = fix_url(href)
|
href = fix_url(href)
|
||||||
if rel in ('http://opds-spec.org/thumbnail', 'http://opds-spec.org/image/thumbnail'):
|
if rel in ('http://opds-spec.org/thumbnail', 'http://opds-spec.org/image/thumbnail'):
|
||||||
if href.startswith('data:image/png;base64,'):
|
if href.startswith('data:image/png;base64,'):
|
||||||
s.cover_data = base64.b64decode(href.replace('data:image/png;base64,', ''))
|
cdata = href.replace('data:image/png;base64,', '')
|
||||||
|
if not isinstance(cdata, bytes):
|
||||||
|
cdata = cdata.encode('ascii')
|
||||||
|
s.cover_data = base64.b64decode(cdata)
|
||||||
|
|
||||||
yield s
|
yield s
|
||||||
|
|
||||||
@ -123,6 +126,7 @@ class GutenbergStore(BasicStoreConfig, OpenSearchOPDSStore):
|
|||||||
for result in search(query, max_results, timeout):
|
for result in search(query, max_results, timeout):
|
||||||
yield result
|
yield result
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import sys
|
import sys
|
||||||
for result in search(' '.join(sys.argv[1:]), write_raw_to='/t/gutenberg.html'):
|
for result in search(' '.join(sys.argv[1:]), write_raw_to='/t/gutenberg.html'):
|
||||||
|
@ -24,6 +24,15 @@ from calibre.gui2.store.search_result import SearchResult
|
|||||||
from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||||
|
|
||||||
|
|
||||||
|
def as_base64(data):
|
||||||
|
if not isinstance(data, bytes):
|
||||||
|
data = data.encode('utf-8')
|
||||||
|
ans = b64encode(data)
|
||||||
|
if isinstance(ans, bytes):
|
||||||
|
ans = ans.decode('ascii')
|
||||||
|
return ans
|
||||||
|
|
||||||
|
|
||||||
class LegimiStore(BasicStoreConfig, StorePlugin):
|
class LegimiStore(BasicStoreConfig, StorePlugin):
|
||||||
|
|
||||||
def open(self, parent=None, detail_item=None, external=False):
|
def open(self, parent=None, detail_item=None, external=False):
|
||||||
@ -31,11 +40,11 @@ class LegimiStore(BasicStoreConfig, StorePlugin):
|
|||||||
|
|
||||||
url = 'https://www.legimi.pl/ebooki/'
|
url = 'https://www.legimi.pl/ebooki/'
|
||||||
|
|
||||||
aff_url = aff_root + str(b64encode(url))
|
aff_url = aff_root + as_base64(url)
|
||||||
|
|
||||||
detail_url = None
|
detail_url = None
|
||||||
if detail_item:
|
if detail_item:
|
||||||
detail_url = aff_root + str(b64encode(detail_item))
|
detail_url = aff_root + as_base64(detail_item)
|
||||||
|
|
||||||
if external or self.config.get('open_external', False):
|
if external or self.config.get('open_external', False):
|
||||||
open_url(QUrl(url_slash_cleaner(detail_url if detail_url else aff_url)))
|
open_url(QUrl(url_slash_cleaner(detail_url if detail_url else aff_url)))
|
||||||
|
@ -23,17 +23,26 @@ from calibre.gui2.store.search_result import SearchResult
|
|||||||
from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||||
|
|
||||||
|
|
||||||
|
def as_base64(data):
|
||||||
|
if not isinstance(data, bytes):
|
||||||
|
data = data.encode('utf-8')
|
||||||
|
ans = b64encode(data)
|
||||||
|
if isinstance(ans, bytes):
|
||||||
|
ans = ans.decode('ascii')
|
||||||
|
return ans
|
||||||
|
|
||||||
|
|
||||||
class PublioStore(BasicStoreConfig, StorePlugin):
|
class PublioStore(BasicStoreConfig, StorePlugin):
|
||||||
|
|
||||||
def open(self, parent=None, detail_item=None, external=False):
|
def open(self, parent=None, detail_item=None, external=False):
|
||||||
aff_root = 'https://www.a4b-tracking.com/pl/stat-click-text-link/29/58/'
|
aff_root = 'https://www.a4b-tracking.com/pl/stat-click-text-link/29/58/'
|
||||||
url = 'http://www.publio.pl/'
|
url = 'http://www.publio.pl/'
|
||||||
|
|
||||||
aff_url = aff_root + str(b64encode(url))
|
aff_url = aff_root + as_base64(url)
|
||||||
|
|
||||||
detail_url = None
|
detail_url = None
|
||||||
if detail_item:
|
if detail_item:
|
||||||
detail_url = aff_root + str(b64encode(detail_item))
|
detail_url = aff_root + as_base64(detail_item)
|
||||||
|
|
||||||
if external or self.config.get('open_external', False):
|
if external or self.config.get('open_external', False):
|
||||||
open_url(QUrl(url_slash_cleaner(detail_url if detail_url else aff_url)))
|
open_url(QUrl(url_slash_cleaner(detail_url if detail_url else aff_url)))
|
||||||
|
@ -23,6 +23,15 @@ from calibre.gui2.store.search_result import SearchResult
|
|||||||
from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||||
|
|
||||||
|
|
||||||
|
def as_base64(data):
|
||||||
|
if not isinstance(data, bytes):
|
||||||
|
data = data.encode('utf-8')
|
||||||
|
ans = b64encode(data)
|
||||||
|
if isinstance(ans, bytes):
|
||||||
|
ans = ans.decode('ascii')
|
||||||
|
return ans
|
||||||
|
|
||||||
|
|
||||||
class SwiatEbookowStore(BasicStoreConfig, StorePlugin):
|
class SwiatEbookowStore(BasicStoreConfig, StorePlugin):
|
||||||
|
|
||||||
def open(self, parent=None, detail_item=None, external=False):
|
def open(self, parent=None, detail_item=None, external=False):
|
||||||
@ -30,11 +39,11 @@ class SwiatEbookowStore(BasicStoreConfig, StorePlugin):
|
|||||||
|
|
||||||
url = 'https://www.swiatebookow.pl/'
|
url = 'https://www.swiatebookow.pl/'
|
||||||
|
|
||||||
aff_url = aff_root + str(b64encode(url))
|
aff_url = aff_root + as_base64(url)
|
||||||
|
|
||||||
detail_url = None
|
detail_url = None
|
||||||
if detail_item:
|
if detail_item:
|
||||||
detail_url = aff_root + str(b64encode(detail_item))
|
detail_url = aff_root + as_base64(detail_item)
|
||||||
|
|
||||||
if external or self.config.get('open_external', False):
|
if external or self.config.get('open_external', False):
|
||||||
open_url(QUrl(url_slash_cleaner(detail_url if detail_url else aff_url)))
|
open_url(QUrl(url_slash_cleaner(detail_url if detail_url else aff_url)))
|
||||||
|
@ -24,6 +24,15 @@ from calibre.gui2.store.search_result import SearchResult
|
|||||||
from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||||
|
|
||||||
|
|
||||||
|
def as_base64(data):
|
||||||
|
if not isinstance(data, bytes):
|
||||||
|
data = data.encode('utf-8')
|
||||||
|
ans = b64encode(data)
|
||||||
|
if isinstance(ans, bytes):
|
||||||
|
ans = ans.decode('ascii')
|
||||||
|
return ans
|
||||||
|
|
||||||
|
|
||||||
class VirtualoStore(BasicStoreConfig, StorePlugin):
|
class VirtualoStore(BasicStoreConfig, StorePlugin):
|
||||||
|
|
||||||
def open(self, parent=None, detail_item=None, external=False):
|
def open(self, parent=None, detail_item=None, external=False):
|
||||||
@ -31,11 +40,11 @@ class VirtualoStore(BasicStoreConfig, StorePlugin):
|
|||||||
|
|
||||||
url = 'http://virtualo.pl/ebook/c2/'
|
url = 'http://virtualo.pl/ebook/c2/'
|
||||||
|
|
||||||
aff_url = aff_root + str(b64encode(url))
|
aff_url = aff_root + as_base64(url)
|
||||||
|
|
||||||
detail_url = None
|
detail_url = None
|
||||||
if detail_item:
|
if detail_item:
|
||||||
detail_url = aff_root + str(b64encode(detail_item))
|
detail_url = aff_root + as_base64(detail_item)
|
||||||
|
|
||||||
if external or self.config.get('open_external', False):
|
if external or self.config.get('open_external', False):
|
||||||
open_url(QUrl(url_slash_cleaner(detail_url if detail_url else aff_url)))
|
open_url(QUrl(url_slash_cleaner(detail_url if detail_url else aff_url)))
|
||||||
@ -75,7 +84,7 @@ class VirtualoStore(BasicStoreConfig, StorePlugin):
|
|||||||
s.cover_url = cover_url
|
s.cover_url = cover_url
|
||||||
s.title = title.strip()
|
s.title = title.strip()
|
||||||
s.author = author.strip()
|
s.author = author.strip()
|
||||||
s.price = re.sub('\.',',',price.strip())
|
s.price = re.sub(r'\.',',',price.strip())
|
||||||
s.detail_item = id
|
s.detail_item = id
|
||||||
s.formats = ', '.join(formats).upper()
|
s.formats = ', '.join(formats).upper()
|
||||||
s.drm = SearchResult.DRM_UNLOCKED if nodrm else SearchResult.DRM_LOCKED
|
s.drm = SearchResult.DRM_UNLOCKED if nodrm else SearchResult.DRM_LOCKED
|
||||||
|
@ -23,6 +23,15 @@ from calibre.gui2.store.search_result import SearchResult
|
|||||||
from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||||
|
|
||||||
|
|
||||||
|
def as_base64(data):
|
||||||
|
if not isinstance(data, bytes):
|
||||||
|
data = data.encode('utf-8')
|
||||||
|
ans = b64encode(data)
|
||||||
|
if isinstance(ans, bytes):
|
||||||
|
ans = ans.decode('ascii')
|
||||||
|
return ans
|
||||||
|
|
||||||
|
|
||||||
def search(query, max_results=10, timeout=60):
|
def search(query, max_results=10, timeout=60):
|
||||||
url = 'http://woblink.com/publication/ajax?mode=none&query=' + urllib.quote_plus(query.encode('utf-8'))
|
url = 'http://woblink.com/publication/ajax?mode=none&query=' + urllib.quote_plus(query.encode('utf-8'))
|
||||||
if max_results > 10:
|
if max_results > 10:
|
||||||
@ -79,11 +88,11 @@ class WoblinkStore(BasicStoreConfig, StorePlugin):
|
|||||||
aff_root = 'https://www.a4b-tracking.com/pl/stat-click-text-link/16/58/'
|
aff_root = 'https://www.a4b-tracking.com/pl/stat-click-text-link/16/58/'
|
||||||
url = 'http://woblink.com/publication'
|
url = 'http://woblink.com/publication'
|
||||||
|
|
||||||
aff_url = aff_root + str(b64encode(url))
|
aff_url = aff_root + as_base64(url)
|
||||||
detail_url = None
|
detail_url = None
|
||||||
|
|
||||||
if detail_item:
|
if detail_item:
|
||||||
detail_url = aff_root + str(b64encode('http://woblink.com' + detail_item))
|
detail_url = aff_root + as_base64('http://woblink.com' + detail_item)
|
||||||
|
|
||||||
if external or self.config.get('open_external', False):
|
if external or self.config.get('open_external', False):
|
||||||
open_url(QUrl(url_slash_cleaner(detail_url if detail_url else aff_url)))
|
open_url(QUrl(url_slash_cleaner(detail_url if detail_url else aff_url)))
|
||||||
|
@ -8,7 +8,6 @@ __copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
|
|||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
import json
|
import json
|
||||||
from base64 import b64encode
|
|
||||||
|
|
||||||
from PyQt5.Qt import (QWidget, QGridLayout, QListWidget, QSize, Qt, QUrl,
|
from PyQt5.Qt import (QWidget, QGridLayout, QListWidget, QSize, Qt, QUrl,
|
||||||
pyqtSlot, pyqtSignal, QVBoxLayout, QFrame, QLabel,
|
pyqtSlot, pyqtSignal, QVBoxLayout, QFrame, QLabel,
|
||||||
@ -20,6 +19,7 @@ from calibre.ebooks.oeb.display.webview import load_html
|
|||||||
from calibre.gui2 import error_dialog, question_dialog, gprefs, secure_web_page
|
from calibre.gui2 import error_dialog, question_dialog, gprefs, secure_web_page
|
||||||
from calibre.utils.logging import default_log
|
from calibre.utils.logging import default_log
|
||||||
from polyglot.builtins import unicode_type, range
|
from polyglot.builtins import unicode_type, range
|
||||||
|
from polyglot.binary import as_base64_unicode
|
||||||
|
|
||||||
|
|
||||||
class Page(QWebPage): # {{{
|
class Page(QWebPage): # {{{
|
||||||
@ -77,7 +77,7 @@ class WebView(QWebView): # {{{
|
|||||||
'''
|
'''
|
||||||
raw = '::selection {background:#ffff00; color:#000;}\n'+raw
|
raw = '::selection {background:#ffff00; color:#000;}\n'+raw
|
||||||
data = 'data:text/css;charset=utf-8;base64,'
|
data = 'data:text/css;charset=utf-8;base64,'
|
||||||
data += b64encode(raw.encode('utf-8'))
|
data += as_base64_unicode(raw)
|
||||||
self.settings().setUserStyleSheetUrl(QUrl(data))
|
self.settings().setUserStyleSheetUrl(QUrl(data))
|
||||||
|
|
||||||
def load_js(self):
|
def load_js(self):
|
||||||
|
@ -8,7 +8,6 @@ __copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
|
|||||||
|
|
||||||
import time, textwrap, json
|
import time, textwrap, json
|
||||||
from bisect import bisect_right
|
from bisect import bisect_right
|
||||||
from base64 import b64encode
|
|
||||||
from polyglot.builtins import map, unicode_type
|
from polyglot.builtins import map, unicode_type
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from functools import partial
|
from functools import partial
|
||||||
@ -31,6 +30,7 @@ from calibre.gui2.widgets2 import HistoryLineEdit2
|
|||||||
from calibre.utils.ipc.simple_worker import offload_worker
|
from calibre.utils.ipc.simple_worker import offload_worker
|
||||||
from polyglot.urllib import urlparse
|
from polyglot.urllib import urlparse
|
||||||
from polyglot.queue import Queue, Empty
|
from polyglot.queue import Queue, Empty
|
||||||
|
from polyglot.binary import as_base64_unicode
|
||||||
|
|
||||||
shutdown = object()
|
shutdown = object()
|
||||||
|
|
||||||
@ -269,7 +269,7 @@ class WebPage(QWebPage):
|
|||||||
settings.setDefaultTextEncoding('utf-8')
|
settings.setDefaultTextEncoding('utf-8')
|
||||||
data = 'data:text/css;charset=utf-8;base64,'
|
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 }'
|
css = '[data-in-split-mode="1"] [data-is-block="1"]:hover { cursor: pointer !important; border-top: solid 5px green !important }'
|
||||||
data += b64encode(css.encode('utf-8'))
|
data += as_base64_unicode(css)
|
||||||
settings.setUserStyleSheetUrl(QUrl(data))
|
settings.setUserStyleSheetUrl(QUrl(data))
|
||||||
|
|
||||||
self.setNetworkAccessManager(NetworkAccessManager(self))
|
self.setNetworkAccessManager(NetworkAccessManager(self))
|
||||||
|
@ -5,7 +5,6 @@ __docformat__ = 'restructuredtext en'
|
|||||||
|
|
||||||
# Imports {{{
|
# Imports {{{
|
||||||
import math, json
|
import math, json
|
||||||
from base64 import b64encode
|
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from polyglot.builtins import iteritems, map, unicode_type, string_or_bytes
|
from polyglot.builtins import iteritems, map, unicode_type, string_or_bytes
|
||||||
|
|
||||||
@ -33,6 +32,7 @@ from calibre.gui2.viewer.footnote import Footnotes
|
|||||||
from calibre.gui2.viewer.fake_net import NetworkAccessManager
|
from calibre.gui2.viewer.fake_net import NetworkAccessManager
|
||||||
from calibre.ebooks.oeb.display.webview import load_html
|
from calibre.ebooks.oeb.display.webview import load_html
|
||||||
from calibre.constants import isxp, iswindows, DEBUG, __version__
|
from calibre.constants import isxp, iswindows, DEBUG, __version__
|
||||||
|
from polyglot.binary import as_base64_unicode
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ class Document(QWebPage): # {{{
|
|||||||
raw = prefix + opts.user_css
|
raw = prefix + opts.user_css
|
||||||
raw = '::selection {background:#ffff00; color:#000;}\n'+raw
|
raw = '::selection {background:#ffff00; color:#000;}\n'+raw
|
||||||
data = 'data:text/css;charset=utf-8;base64,'
|
data = 'data:text/css;charset=utf-8;base64,'
|
||||||
data += b64encode(raw.encode('utf-8'))
|
data += as_base64_unicode(raw)
|
||||||
self.settings().setUserStyleSheetUrl(QUrl(data))
|
self.settings().setUserStyleSheetUrl(QUrl(data))
|
||||||
|
|
||||||
def findText(self, q, flags):
|
def findText(self, q, flags):
|
||||||
|
@ -6,7 +6,7 @@ from __future__ import (unicode_literals, division, absolute_import,
|
|||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2015, Kovid Goyal <kovid at kovidgoyal.net>'
|
__copyright__ = '2015, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
|
|
||||||
import binascii, os, random, struct, base64
|
import binascii, os, random, struct
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from hashlib import md5, sha256
|
from hashlib import md5, sha256
|
||||||
from itertools import permutations
|
from itertools import permutations
|
||||||
@ -17,6 +17,7 @@ from calibre.srv.http_request import parse_uri
|
|||||||
from calibre.srv.utils import parse_http_dict, encode_path
|
from calibre.srv.utils import parse_http_dict, encode_path
|
||||||
from calibre.utils.monotonic import monotonic
|
from calibre.utils.monotonic import monotonic
|
||||||
from polyglot import http_client
|
from polyglot import http_client
|
||||||
|
from polyglot.binary import from_base64_unicode
|
||||||
|
|
||||||
MAX_AGE_SECONDS = 3600
|
MAX_AGE_SECONDS = 3600
|
||||||
nonce_counter, nonce_counter_lock = 0, Lock()
|
nonce_counter, nonce_counter_lock = 0, Lock()
|
||||||
@ -76,7 +77,7 @@ def sha256_hex(s):
|
|||||||
|
|
||||||
|
|
||||||
def base64_decode(s):
|
def base64_decode(s):
|
||||||
return base64.standard_b64decode(as_bytestring(s)).decode('utf-8')
|
return from_base64_unicode(s)
|
||||||
|
|
||||||
|
|
||||||
def synthesize_nonce(key_order, realm, secret, timestamp=None):
|
def synthesize_nonce(key_order, realm, secret, timestamp=None):
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from base64 import standard_b64decode
|
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
@ -20,6 +19,7 @@ from calibre.srv.utils import get_db, get_library_data
|
|||||||
from calibre.utils.imghdr import what
|
from calibre.utils.imghdr import what
|
||||||
from calibre.utils.serialize import MSGPACK_MIME, json_loads, msgpack_loads
|
from calibre.utils.serialize import MSGPACK_MIME, json_loads, msgpack_loads
|
||||||
from polyglot.builtins import iteritems
|
from polyglot.builtins import iteritems
|
||||||
|
from polyglot.binary import from_base64_bytes
|
||||||
|
|
||||||
receive_data_methods = {'GET', 'POST'}
|
receive_data_methods = {'GET', 'POST'}
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ def cdb_set_fields(ctx, rd, book_id, library_id):
|
|||||||
if cdata is not False:
|
if cdata is not False:
|
||||||
if cdata is not None:
|
if cdata is not None:
|
||||||
try:
|
try:
|
||||||
cdata = standard_b64decode(cdata.split(',', 1)[-1].encode('ascii'))
|
cdata = from_base64_bytes(cdata.split(',', 1)[-1])
|
||||||
except Exception:
|
except Exception:
|
||||||
raise HTTPBadRequest('Cover data is not valid base64 encoded data')
|
raise HTTPBadRequest('Cover data is not valid base64 encoded data')
|
||||||
try:
|
try:
|
||||||
|
@ -2,31 +2,35 @@
|
|||||||
# vim:fileencoding=utf-8
|
# vim:fileencoding=utf-8
|
||||||
# License: GPLv3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
# License: GPLv3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
from __future__ import (unicode_literals, division, absolute_import,
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
print_function)
|
|
||||||
import sys, os, json, re
|
import json
|
||||||
from base64 import standard_b64encode, standard_b64decode
|
import os
|
||||||
from collections import defaultdict, OrderedDict
|
import re
|
||||||
from itertools import count
|
import sys
|
||||||
|
from collections import OrderedDict, defaultdict
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
from itertools import count
|
||||||
|
|
||||||
from css_parser import replaceUrls
|
from css_parser import replaceUrls
|
||||||
from css_parser.css import CSSRule
|
from css_parser.css import CSSRule
|
||||||
|
|
||||||
from calibre import prepare_string_for_xml, force_unicode
|
from calibre import force_unicode, prepare_string_for_xml
|
||||||
from calibre.ebooks import parse_css_length
|
from calibre.ebooks import parse_css_length
|
||||||
|
from calibre.ebooks.css_transform_rules import StyleDeclaration
|
||||||
from calibre.ebooks.oeb.base import (
|
from calibre.ebooks.oeb.base import (
|
||||||
OEB_DOCS, OEB_STYLES, rewrite_links, XPath, urlunquote, XLINK, XHTML_NS, OPF, XHTML, EPUB_NS)
|
EPUB_NS, OEB_DOCS, OEB_STYLES, OPF, XHTML, XHTML_NS, XLINK, XPath, rewrite_links,
|
||||||
|
urlunquote
|
||||||
|
)
|
||||||
from calibre.ebooks.oeb.iterator.book import extract_book
|
from calibre.ebooks.oeb.iterator.book import extract_book
|
||||||
from calibre.ebooks.oeb.polish.container import Container as ContainerBase
|
from calibre.ebooks.oeb.polish.container import Container as ContainerBase
|
||||||
from calibre.ebooks.oeb.polish.cover import set_epub_cover, find_cover_image
|
from calibre.ebooks.oeb.polish.cover import find_cover_image, set_epub_cover
|
||||||
from calibre.ebooks.oeb.polish.css import transform_css
|
from calibre.ebooks.oeb.polish.css import transform_css
|
||||||
from calibre.ebooks.oeb.polish.utils import extract
|
from calibre.ebooks.oeb.polish.toc import get_landmarks, get_toc
|
||||||
from calibre.ebooks.css_transform_rules import StyleDeclaration
|
from calibre.ebooks.oeb.polish.utils import extract, guess_type
|
||||||
from calibre.ebooks.oeb.polish.toc import get_toc, get_landmarks
|
|
||||||
from calibre.ebooks.oeb.polish.utils import guess_type
|
|
||||||
from calibre.utils.short_uuid import uuid4
|
|
||||||
from calibre.utils.logging import default_log
|
from calibre.utils.logging import default_log
|
||||||
|
from calibre.utils.short_uuid import uuid4
|
||||||
|
from polyglot.binary import as_base64_unicode as encode_component, from_base64_unicode as decode_component
|
||||||
from polyglot.builtins import iteritems, map, unicode_type
|
from polyglot.builtins import iteritems, map, unicode_type
|
||||||
from polyglot.urllib import quote, urlparse
|
from polyglot.urllib import quote, urlparse
|
||||||
|
|
||||||
@ -35,14 +39,6 @@ RENDER_VERSION = 1
|
|||||||
BLANK_JPEG = b'\xff\xd8\xff\xdb\x00C\x00\x03\x02\x02\x02\x02\x02\x03\x02\x02\x02\x03\x03\x03\x03\x04\x06\x04\x04\x04\x04\x04\x08\x06\x06\x05\x06\t\x08\n\n\t\x08\t\t\n\x0c\x0f\x0c\n\x0b\x0e\x0b\t\t\r\x11\r\x0e\x0f\x10\x10\x11\x10\n\x0c\x12\x13\x12\x10\x13\x0f\x10\x10\x10\xff\xc9\x00\x0b\x08\x00\x01\x00\x01\x01\x01\x11\x00\xff\xcc\x00\x06\x00\x10\x10\x05\xff\xda\x00\x08\x01\x01\x00\x00?\x00\xd2\xcf \xff\xd9' # noqa
|
BLANK_JPEG = b'\xff\xd8\xff\xdb\x00C\x00\x03\x02\x02\x02\x02\x02\x03\x02\x02\x02\x03\x03\x03\x03\x04\x06\x04\x04\x04\x04\x04\x08\x06\x06\x05\x06\t\x08\n\n\t\x08\t\t\n\x0c\x0f\x0c\n\x0b\x0e\x0b\t\t\r\x11\r\x0e\x0f\x10\x10\x11\x10\n\x0c\x12\x13\x12\x10\x13\x0f\x10\x10\x10\xff\xc9\x00\x0b\x08\x00\x01\x00\x01\x01\x01\x11\x00\xff\xcc\x00\x06\x00\x10\x10\x05\xff\xda\x00\x08\x01\x01\x00\x00?\x00\xd2\xcf \xff\xd9' # noqa
|
||||||
|
|
||||||
|
|
||||||
def encode_component(x):
|
|
||||||
return standard_b64encode(x.encode('utf-8')).decode('ascii')
|
|
||||||
|
|
||||||
|
|
||||||
def decode_component(x):
|
|
||||||
return standard_b64decode(x).decode('utf-8')
|
|
||||||
|
|
||||||
|
|
||||||
def encode_url(name, frag=''):
|
def encode_url(name, frag=''):
|
||||||
name = encode_component(name)
|
name = encode_component(name)
|
||||||
if frag:
|
if frag:
|
||||||
|
@ -6,7 +6,7 @@ from __future__ import (unicode_literals, division, absolute_import,
|
|||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2015, Kovid Goyal <kovid at kovidgoyal.net>'
|
__copyright__ = '2015, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
|
|
||||||
import zlib, json, base64, os
|
import zlib, json, os
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
@ -14,11 +14,12 @@ from calibre.ebooks.metadata.meta import get_metadata
|
|||||||
from calibre.srv.tests.base import LibraryBaseTest
|
from calibre.srv.tests.base import LibraryBaseTest
|
||||||
from polyglot.http_client import OK, NOT_FOUND, FORBIDDEN
|
from polyglot.http_client import OK, NOT_FOUND, FORBIDDEN
|
||||||
from polyglot.urllib import urlencode, quote
|
from polyglot.urllib import urlencode, quote
|
||||||
|
from polyglot.binary import as_base64_bytes
|
||||||
|
|
||||||
|
|
||||||
def make_request(conn, url, headers={}, prefix='/ajax', username=None, password=None, method='GET', data=None):
|
def make_request(conn, url, headers={}, prefix='/ajax', username=None, password=None, method='GET', data=None):
|
||||||
if username and password:
|
if username and password:
|
||||||
headers[b'Authorization'] = b'Basic ' + base64.standard_b64encode((username + ':' + password).encode('utf-8'))
|
headers[b'Authorization'] = b'Basic ' + as_base64_bytes((username + ':' + password))
|
||||||
conn.request(method, prefix + url, headers=headers, body=data)
|
conn.request(method, prefix + url, headers=headers, body=data)
|
||||||
r = conn.getresponse()
|
r = conn.getresponse()
|
||||||
data = r.read()
|
data = r.read()
|
||||||
|
@ -6,7 +6,7 @@ from __future__ import (unicode_literals, division, absolute_import,
|
|||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2015, Kovid Goyal <kovid at kovidgoyal.net>'
|
__copyright__ = '2015, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
|
|
||||||
import base64, subprocess, os, time
|
import subprocess, os, time
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
try:
|
try:
|
||||||
from distutils.spawn import find_executable
|
from distutils.spawn import find_executable
|
||||||
@ -22,6 +22,7 @@ from polyglot import http_client
|
|||||||
from polyglot.http_cookie import CookieJar
|
from polyglot.http_cookie import CookieJar
|
||||||
from polyglot.urllib import (build_opener, HTTPBasicAuthHandler,
|
from polyglot.urllib import (build_opener, HTTPBasicAuthHandler,
|
||||||
HTTPCookieProcessor, HTTPDigestAuthHandler, HTTPError)
|
HTTPCookieProcessor, HTTPDigestAuthHandler, HTTPError)
|
||||||
|
from polyglot.binary import as_base64_bytes
|
||||||
|
|
||||||
REALM = 'calibre-test'
|
REALM = 'calibre-test'
|
||||||
|
|
||||||
@ -101,7 +102,7 @@ class TestAuth(BaseTest):
|
|||||||
self.ae(r.status, http_client.UNAUTHORIZED)
|
self.ae(r.status, http_client.UNAUTHORIZED)
|
||||||
self.ae(r.getheader('WWW-Authenticate'), b'Basic realm="%s"' % bytes(REALM))
|
self.ae(r.getheader('WWW-Authenticate'), b'Basic realm="%s"' % bytes(REALM))
|
||||||
self.assertFalse(r.read())
|
self.assertFalse(r.read())
|
||||||
conn.request('GET', '/closed', headers={'Authorization': b'Basic ' + base64.standard_b64encode(b'testuser:testpw')})
|
conn.request('GET', '/closed', headers={'Authorization': b'Basic ' + as_base64_bytes(b'testuser:testpw')})
|
||||||
r = conn.getresponse()
|
r = conn.getresponse()
|
||||||
self.ae(r.read(), b'closed')
|
self.ae(r.read(), b'closed')
|
||||||
self.ae(r.status, http_client.OK)
|
self.ae(r.status, http_client.OK)
|
||||||
@ -109,7 +110,7 @@ class TestAuth(BaseTest):
|
|||||||
self.ae(b'closed', urlopen(server, un='!@#$%^&*()-=_+', pw='!@#$%^&*()-=_+', method='basic').read())
|
self.ae(b'closed', urlopen(server, un='!@#$%^&*()-=_+', pw='!@#$%^&*()-=_+', method='basic').read())
|
||||||
|
|
||||||
def request(un='testuser', pw='testpw'):
|
def request(un='testuser', pw='testpw'):
|
||||||
conn.request('GET', '/closed', headers={'Authorization': b'Basic ' + base64.standard_b64encode(bytes('%s:%s' % (un, pw)))})
|
conn.request('GET', '/closed', headers={'Authorization': b'Basic ' + as_base64_bytes('%s:%s' % (un, pw))})
|
||||||
r = conn.getresponse()
|
r = conn.getresponse()
|
||||||
return r.status, r.read()
|
return r.status, r.read()
|
||||||
|
|
||||||
@ -254,7 +255,7 @@ class TestAuth(BaseTest):
|
|||||||
conn = server.connect()
|
conn = server.connect()
|
||||||
|
|
||||||
def request(un='testuser', pw='testpw'):
|
def request(un='testuser', pw='testpw'):
|
||||||
conn.request('GET', '/closed', headers={'Authorization': b'Basic ' + base64.standard_b64encode(bytes('%s:%s' % (un, pw)))})
|
conn.request('GET', '/closed', headers={'Authorization': b'Basic ' + as_base64_bytes('%s:%s' % (un, pw))})
|
||||||
r = conn.getresponse()
|
r = conn.getresponse()
|
||||||
return r.status, r.read()
|
return r.status, r.read()
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
from __future__ import (unicode_literals, division, absolute_import,
|
from __future__ import (unicode_literals, division, absolute_import,
|
||||||
print_function)
|
print_function)
|
||||||
import socket, os, struct, errno, numbers
|
import socket, os, struct, errno, numbers
|
||||||
from base64 import standard_b64encode
|
|
||||||
from collections import deque, namedtuple
|
from collections import deque, namedtuple
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from hashlib import sha1
|
from hashlib import sha1
|
||||||
@ -17,6 +16,7 @@ from calibre.srv.web_socket import (
|
|||||||
from calibre.utils.monotonic import monotonic
|
from calibre.utils.monotonic import monotonic
|
||||||
from calibre.utils.socket_inheritance import set_socket_inherit
|
from calibre.utils.socket_inheritance import set_socket_inherit
|
||||||
from polyglot.builtins import range, unicode_type
|
from polyglot.builtins import range, unicode_type
|
||||||
|
from polyglot.binary import as_base64_bytes, as_base64_unicode
|
||||||
|
|
||||||
HANDSHAKE_STR = '''\
|
HANDSHAKE_STR = '''\
|
||||||
GET / HTTP/1.1\r
|
GET / HTTP/1.1\r
|
||||||
@ -35,7 +35,7 @@ class WSClient(object):
|
|||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
self.socket = socket.create_connection(('localhost', port), timeout)
|
self.socket = socket.create_connection(('localhost', port), timeout)
|
||||||
set_socket_inherit(self.socket, False)
|
set_socket_inherit(self.socket, False)
|
||||||
self.key = standard_b64encode(os.urandom(8))
|
self.key = as_base64_bytes(os.urandom(8))
|
||||||
self.socket.sendall(HANDSHAKE_STR.format(self.key).encode('ascii'))
|
self.socket.sendall(HANDSHAKE_STR.format(self.key).encode('ascii'))
|
||||||
self.read_buf = deque()
|
self.read_buf = deque()
|
||||||
self.read_upgrade_response()
|
self.read_upgrade_response()
|
||||||
@ -64,7 +64,7 @@ class WSClient(object):
|
|||||||
if rl != b'HTTP/1.1 101 Switching Protocols\r\n':
|
if rl != b'HTTP/1.1 101 Switching Protocols\r\n':
|
||||||
raise ValueError('Server did not respond with correct switching protocols line')
|
raise ValueError('Server did not respond with correct switching protocols line')
|
||||||
headers = read_headers(partial(next, lines))
|
headers = read_headers(partial(next, lines))
|
||||||
key = standard_b64encode(sha1(self.key + GUID_STR).digest())
|
key = as_base64_unicode(sha1(self.key + GUID_STR).digest())
|
||||||
if headers.get('Sec-WebSocket-Accept') != key:
|
if headers.get('Sec-WebSocket-Accept') != key:
|
||||||
raise ValueError('Server did not respond with correct key in Sec-WebSocket-Accept')
|
raise ValueError('Server did not respond with correct key in Sec-WebSocket-Accept')
|
||||||
|
|
||||||
|
@ -2,24 +2,28 @@
|
|||||||
# vim:fileencoding=utf-8
|
# vim:fileencoding=utf-8
|
||||||
# License: GPLv3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
# License: GPLv3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
from __future__ import (unicode_literals, division, absolute_import,
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
print_function)
|
|
||||||
|
|
||||||
import os, weakref, socket
|
import os
|
||||||
from base64 import standard_b64encode
|
import socket
|
||||||
|
import weakref
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from hashlib import sha1
|
from hashlib import sha1
|
||||||
from struct import unpack_from, pack, error as struct_error
|
from struct import error as struct_error, pack, unpack_from
|
||||||
from threading import Lock
|
from threading import Lock
|
||||||
|
|
||||||
from calibre import as_unicode
|
from calibre import as_unicode
|
||||||
from calibre.constants import plugins
|
from calibre.constants import plugins
|
||||||
from calibre.srv.loop import ServerLoop, HandleInterrupt, WRITE, READ, RDWR, Connection
|
|
||||||
from calibre.srv.http_response import HTTPConnection, create_http_handler
|
from calibre.srv.http_response import HTTPConnection, create_http_handler
|
||||||
|
from calibre.srv.loop import (
|
||||||
|
RDWR, READ, WRITE, Connection, HandleInterrupt, ServerLoop
|
||||||
|
)
|
||||||
from calibre.srv.utils import DESIRED_SEND_BUFFER_SIZE
|
from calibre.srv.utils import DESIRED_SEND_BUFFER_SIZE
|
||||||
from calibre.utils.speedups import ReadOnlyFileBuffer
|
from calibre.utils.speedups import ReadOnlyFileBuffer
|
||||||
from polyglot.queue import Queue, Empty
|
|
||||||
from polyglot import http_client
|
from polyglot import http_client
|
||||||
|
from polyglot.binary import as_base64_unicode
|
||||||
|
from polyglot.queue import Empty, Queue
|
||||||
|
|
||||||
speedup, err = plugins['speedup']
|
speedup, err = plugins['speedup']
|
||||||
if not speedup:
|
if not speedup:
|
||||||
raise RuntimeError('Failed to load speedup module with error: ' + err)
|
raise RuntimeError('Failed to load speedup module with error: ' + err)
|
||||||
@ -291,7 +295,7 @@ class WebSocketConnection(HTTPConnection):
|
|||||||
if self.method != 'GET':
|
if self.method != 'GET':
|
||||||
return self.simple_response(http_client.BAD_REQUEST, 'Invalid WebSocket method: %s' % self.method)
|
return self.simple_response(http_client.BAD_REQUEST, 'Invalid WebSocket method: %s' % self.method)
|
||||||
|
|
||||||
response = HANDSHAKE_STR % standard_b64encode(sha1(key + GUID_STR).digest())
|
response = HANDSHAKE_STR % as_base64_unicode(sha1(key + GUID_STR).digest())
|
||||||
self.optimize_for_sending_packet()
|
self.optimize_for_sending_packet()
|
||||||
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
||||||
self.set_state(WRITE, self.upgrade_connection_to_ws, ReadOnlyFileBuffer(response.encode('ascii')), inheaders)
|
self.set_state(WRITE, self.upgrade_connection_to_ws, ReadOnlyFileBuffer(response.encode('ascii')), inheaders)
|
||||||
|
@ -21,9 +21,9 @@ plugin_dir = os.path.join(config_dir, 'plugins')
|
|||||||
def to_json(obj):
|
def to_json(obj):
|
||||||
import datetime
|
import datetime
|
||||||
if isinstance(obj, bytearray):
|
if isinstance(obj, bytearray):
|
||||||
import base64
|
from base64 import standard_b64encode
|
||||||
return {'__class__': 'bytearray',
|
return {'__class__': 'bytearray',
|
||||||
'__value__': base64.standard_b64encode(bytes(obj)).decode('ascii')}
|
'__value__': standard_b64encode(bytes(obj)).decode('ascii')}
|
||||||
if isinstance(obj, datetime.datetime):
|
if isinstance(obj, datetime.datetime):
|
||||||
from calibre.utils.date import isoformat
|
from calibre.utils.date import isoformat
|
||||||
return {'__class__': 'datetime.datetime',
|
return {'__class__': 'datetime.datetime',
|
||||||
@ -42,8 +42,8 @@ def from_json(obj):
|
|||||||
custom = obj.get('__class__')
|
custom = obj.get('__class__')
|
||||||
if custom is not None:
|
if custom is not None:
|
||||||
if custom == 'bytearray':
|
if custom == 'bytearray':
|
||||||
import base64
|
from base64 import standard_b64decode
|
||||||
return bytearray(base64.standard_b64decode(obj['__value__']))
|
return bytearray(standard_b64decode(obj['__value__'].encode('ascii')))
|
||||||
if custom == 'datetime.datetime':
|
if custom == 'datetime.datetime':
|
||||||
from calibre.utils.iso8601 import parse_iso8601
|
from calibre.utils.iso8601 import parse_iso8601
|
||||||
return parse_iso8601(obj['__value__'], assume_utc=True)
|
return parse_iso8601(obj['__value__'], assume_utc=True)
|
||||||
|
@ -66,13 +66,11 @@ def json_dumps(data, **kw):
|
|||||||
|
|
||||||
|
|
||||||
def decode_metadata(x, for_json):
|
def decode_metadata(x, for_json):
|
||||||
import base64
|
from polyglot.binary import from_base64_bytes
|
||||||
from calibre.ebooks.metadata.book.serialize import metadata_from_dict
|
from calibre.ebooks.metadata.book.serialize import metadata_from_dict
|
||||||
obj = metadata_from_dict(x)
|
obj = metadata_from_dict(x)
|
||||||
if for_json and obj.cover_data and obj.cover_data[1]:
|
if for_json and obj.cover_data and obj.cover_data[1]:
|
||||||
obj.cover_data = obj.cover_data[0], base64.standard_b64decode(
|
obj.cover_data = obj.cover_data[0], from_base64_bytes(obj.cover_data[1])
|
||||||
obj.cover_data[1]
|
|
||||||
)
|
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ import sys
|
|||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
from base64 import b64decode
|
|
||||||
|
|
||||||
from calibre import browser, relpath, unicode_path
|
from calibre import browser, relpath, unicode_path
|
||||||
from calibre.constants import filesystem_encoding, iswindows
|
from calibre.constants import filesystem_encoding, iswindows
|
||||||
@ -35,6 +34,7 @@ from polyglot.urllib import (
|
|||||||
URLError, quote, url2pathname, urljoin, urlparse, urlsplit, urlunparse,
|
URLError, quote, url2pathname, urljoin, urlparse, urlsplit, urlunparse,
|
||||||
urlunsplit
|
urlunsplit
|
||||||
)
|
)
|
||||||
|
from polyglot.binary import from_base64_bytes
|
||||||
|
|
||||||
|
|
||||||
class AbortArticle(Exception):
|
class AbortArticle(Exception):
|
||||||
@ -391,8 +391,8 @@ class RecursiveFetcher(object):
|
|||||||
iurl = tag['src']
|
iurl = tag['src']
|
||||||
if iurl.startswith('data:image/'):
|
if iurl.startswith('data:image/'):
|
||||||
try:
|
try:
|
||||||
data = b64decode(iurl.partition(',')[-1])
|
data = from_base64_bytes(iurl.partition(',')[-1])
|
||||||
except:
|
except Exception:
|
||||||
self.log.exception('Failed to decode embedded image')
|
self.log.exception('Failed to decode embedded image')
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
|
32
src/polyglot/binary.py
Normal file
32
src/polyglot/binary.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env python2
|
||||||
|
# vim:fileencoding=utf-8
|
||||||
|
# License: GPL v3 Copyright: 2019, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
|
from base64 import standard_b64encode, standard_b64decode
|
||||||
|
from polyglot.builtins import unicode_type
|
||||||
|
|
||||||
|
|
||||||
|
def as_base64_bytes(x, enc='utf-8'):
|
||||||
|
if isinstance(x, unicode_type):
|
||||||
|
x = x.encode(enc)
|
||||||
|
return standard_b64encode(x)
|
||||||
|
|
||||||
|
|
||||||
|
def as_base64_unicode(x, enc='utf-8'):
|
||||||
|
if isinstance(x, unicode_type):
|
||||||
|
x = x.encode(enc)
|
||||||
|
return standard_b64encode(x).decode('ascii')
|
||||||
|
|
||||||
|
|
||||||
|
def from_base64_unicode(x, enc='utf-8'):
|
||||||
|
if isinstance(x, unicode_type):
|
||||||
|
x = x.encode('ascii')
|
||||||
|
return standard_b64decode(x).decode(enc)
|
||||||
|
|
||||||
|
|
||||||
|
def from_base64_bytes(x):
|
||||||
|
if isinstance(x, unicode_type):
|
||||||
|
x = x.encode('ascii')
|
||||||
|
return standard_b64decode(x)
|
Loading…
x
Reference in New Issue
Block a user