%PDF- %PDF-
| Direktori : /lib/calibre/calibre/gui2/ |
| Current File : //lib/calibre/calibre/gui2/ebook_download.py |
__license__ = 'GPL 3'
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en'
import os
import shutil
from contextlib import closing
from mechanize import MozillaCookieJar
from calibre import browser
from calibre.ebooks import BOOK_EXTENSIONS
from calibre.gui2 import Dispatcher, gprefs
from calibre.gui2.dialogs.message_box import MessageBox
from calibre.gui2.threaded_jobs import ThreadedJob
from calibre.ptempfile import PersistentTemporaryDirectory
from calibre.utils.filenames import ascii_filename
from calibre.web import get_download_filename_from_response
from polyglot.builtins import string_or_bytes, as_unicode
class DownloadInfo(MessageBox):
def __init__(self, filename, parent=None):
MessageBox.__init__(
self, MessageBox.INFO, _('Downloading book'), _(
'The book {0} will be downloaded and added to your'
' calibre library automatically.').format(filename),
show_copy_button=False, parent=parent
)
self.toggle_checkbox.setChecked(True)
self.toggle_checkbox.setVisible(True)
self.toggle_checkbox.setText(_('Show this message again'))
self.toggle_checkbox.toggled.connect(self.show_again_changed)
self.resize_needed.emit()
def show_again_changed(self):
gprefs.set('show_get_books_download_info', self.toggle_checkbox.isChecked())
def show_download_info(filename, parent=None):
if not gprefs.get('show_get_books_download_info', True):
return
DownloadInfo(filename, parent).exec()
def get_download_filename(response):
filename = get_download_filename_from_response(response)
filename, ext = os.path.splitext(filename)
filename = filename[:60] + ext
filename = ascii_filename(filename)
return filename
def download_file(url, cookie_file=None, filename=None, create_browser=None):
if url.startswith('//'):
url = 'http:' + url
try:
br = browser() if create_browser is None else create_browser()
except NotImplementedError:
br = browser()
if cookie_file:
cj = MozillaCookieJar()
cj.load(cookie_file)
br.set_cookiejar(cj)
with closing(br.open(url)) as r:
if not filename:
filename = get_download_filename(r)
temp_path = os.path.join(PersistentTemporaryDirectory(), filename)
with open(temp_path, 'w+b') as tf:
shutil.copyfileobj(r, tf)
dfilename = tf.name
return dfilename
class EbookDownload:
def __call__(self, gui, cookie_file=None, url='', filename='', save_loc='', add_to_lib=True, tags=[], create_browser=None,
log=None, abort=None, notifications=None):
dfilename = ''
try:
dfilename = self._download(cookie_file, url, filename, save_loc, add_to_lib, create_browser)
self._add(dfilename, gui, add_to_lib, tags)
self._save_as(dfilename, save_loc)
finally:
try:
if dfilename:
os.remove(dfilename)
except:
pass
def _download(self, cookie_file, url, filename, save_loc, add_to_lib, create_browser):
if not url:
raise Exception(_('No file specified to download.'))
if not save_loc and not add_to_lib:
# Nothing to do.
return ''
return download_file(url, cookie_file, filename, create_browser=create_browser)
def _add(self, filename, gui, add_to_lib, tags):
if not add_to_lib or not filename:
return
ext = os.path.splitext(filename)[1][1:].lower()
if ext not in BOOK_EXTENSIONS:
raise Exception(_('Not a support e-book format.'))
from calibre.ebooks.metadata.meta import get_metadata
with open(filename, 'rb') as f:
mi = get_metadata(f, ext, force_read_metadata=True)
mi.tags.extend(tags)
id = gui.library_view.model().db.create_book_entry(mi)
gui.library_view.model().db.add_format_with_hooks(id, ext.upper(), filename, index_is_id=True)
gui.library_view.model().books_added(1)
gui.library_view.model().count_changed()
def _save_as(self, dfilename, save_loc):
if not save_loc or not dfilename:
return
shutil.copy(dfilename, save_loc)
gui_ebook_download = EbookDownload()
def start_ebook_download(callback, job_manager, gui, cookie_file=None, url='', filename='', save_loc='', add_to_lib=True, tags=[], create_browser=None):
description = _('Downloading %s') % as_unicode(filename or url, errors='replace')
job = ThreadedJob('ebook_download', description, gui_ebook_download, (
gui, cookie_file, url, filename, save_loc, add_to_lib, tags, create_browser), {},
callback, max_concurrent_count=2, killable=False)
job_manager.run_threaded_job(job)
class EbookDownloadMixin:
def __init__(self, *args, **kwargs):
pass
def download_ebook(self, url='', cookie_file=None, filename='', save_loc='', add_to_lib=True, tags=[], create_browser=None):
if tags:
if isinstance(tags, string_or_bytes):
tags = tags.split(',')
start_ebook_download(Dispatcher(self.downloaded_ebook), self.job_manager, self, cookie_file, url, filename, save_loc, add_to_lib, tags, create_browser)
self.status_bar.show_message(_('Downloading') + ' ' + as_unicode(filename or url, errors='replace'), 3000)
def downloaded_ebook(self, job):
if job.failed:
self.job_exception(job, dialog_title=_('Failed to download e-book'))
return
self.status_bar.show_message(job.description + ' ' + _('finished'), 5000)