mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Add action to save only specified format when saving to disk
This commit is contained in:
parent
476e9371bb
commit
7b498bf908
@ -15,6 +15,6 @@ class ConversionError(Exception):
|
||||
class UnknownFormatError(Exception):
|
||||
pass
|
||||
|
||||
BOOK_EXTENSIONS = ['lrf', 'lrx', 'rar', 'zip', 'rtf', 'lit', 'txt', 'htm', 'xhtm',
|
||||
BOOK_EXTENSIONS = ['lrf', 'rar', 'zip', 'rtf', 'lit', 'txt', 'htm', 'xhtm',
|
||||
'html', 'xhtml', 'epub', 'pdf', 'prc', 'mobi', 'azw',
|
||||
'epub', 'fb2', 'djvu']
|
||||
'epub', 'fb2', 'djvu', 'lrx']
|
||||
|
@ -222,7 +222,7 @@ class MobiReader(object):
|
||||
tocobj = TOC()
|
||||
for a in soup.findAll('a', href=True):
|
||||
try:
|
||||
text = ''.join(a.findAll(text=True))
|
||||
text = ''.join(a.findAll(text=True)).strip()
|
||||
except:
|
||||
text = ''
|
||||
tocobj.add_item(toc.partition('#')[0], a['href'][1:], text)
|
||||
|
@ -3,12 +3,13 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
import os
|
||||
|
||||
from PyQt4.QtGui import QDialog, QMessageBox, QListWidgetItem, QIcon
|
||||
from PyQt4.QtCore import SIGNAL, QTimer, Qt, QSize
|
||||
from PyQt4.QtCore import SIGNAL, QTimer, Qt, QSize, QVariant
|
||||
|
||||
from calibre import islinux, Settings
|
||||
from calibre.gui2.dialogs.config_ui import Ui_Dialog
|
||||
from calibre.gui2 import qstring_to_unicode, choose_dir, error_dialog
|
||||
from calibre.gui2.widgets import FilenamePattern
|
||||
from calibre.ebooks import BOOK_EXTENSIONS
|
||||
|
||||
|
||||
|
||||
@ -59,6 +60,11 @@ class ConfigDialog(QDialog, Ui_Dialog):
|
||||
self.toolbar_button_size.setCurrentIndex(0 if icons == self.ICON_SIZES[0] else 1 if icons == self.ICON_SIZES[1] else 2)
|
||||
self.show_toolbar_text.setChecked(settings.get('show text in toolbar', True))
|
||||
|
||||
for ext in BOOK_EXTENSIONS:
|
||||
self.single_format.addItem(ext.upper(), QVariant(ext))
|
||||
|
||||
single_format = settings.get('save to disk single format', 'lrf')
|
||||
self.single_format.setCurrentIndex(BOOK_EXTENSIONS.index(single_format))
|
||||
|
||||
def compact(self, toggled):
|
||||
d = Vacuum(self, self.db)
|
||||
@ -89,6 +95,8 @@ class ConfigDialog(QDialog, Ui_Dialog):
|
||||
settings.set('show text in toolbar', bool(self.show_toolbar_text.isChecked()))
|
||||
pattern = self.filename_pattern.commit()
|
||||
settings.set('filename pattern', pattern)
|
||||
settings.set('save to disk single format', BOOK_EXTENSIONS[self.single_format.currentIndex()])
|
||||
|
||||
|
||||
if not path or not os.path.exists(path) or not os.path.isdir(path):
|
||||
d = error_dialog(self, _('Invalid database location'), _('Invalid database location ')+path+_('<br>Must be a directory.'))
|
||||
|
@ -1,4 +1,5 @@
|
||||
<ui version="4.0" >
|
||||
<author>Kovid Goyal</author>
|
||||
<class>Dialog</class>
|
||||
<widget class="QDialog" name="Dialog" >
|
||||
<property name="geometry" >
|
||||
@ -76,18 +77,10 @@
|
||||
<property name="currentIndex" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>583</width>
|
||||
<height>625</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<item row="0" column="0" >
|
||||
<layout class="QVBoxLayout" >
|
||||
<widget class="QWidget" name="page_3" >
|
||||
<layout class="QVBoxLayout" name="verticalLayout" >
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="_2" >
|
||||
<item>
|
||||
<widget class="QLabel" name="label" >
|
||||
<property name="text" >
|
||||
@ -99,7 +92,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<layout class="QHBoxLayout" name="_3" >
|
||||
<item>
|
||||
<widget class="QLineEdit" name="location" />
|
||||
</item>
|
||||
@ -121,7 +114,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<item>
|
||||
<widget class="QCheckBox" name="roman_numerals" >
|
||||
<property name="text" >
|
||||
<string>Use &Roman numerals for series number</string>
|
||||
@ -131,9 +124,35 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" >
|
||||
<layout class="QHBoxLayout" >
|
||||
<item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_2" >
|
||||
<item row="0" column="0" >
|
||||
<widget class="QLabel" name="label_5" >
|
||||
<property name="text" >
|
||||
<string>Format for &single file save:</string>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<cstring>single_format</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" >
|
||||
<widget class="QComboBox" name="single_format" />
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<widget class="QLabel" name="label_3" >
|
||||
<property name="text" >
|
||||
<string>&Priority for conversion jobs:</string>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<cstring>priority</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" >
|
||||
<widget class="QComboBox" name="priority" />
|
||||
</item>
|
||||
<item row="2" column="0" >
|
||||
<widget class="QLabel" name="label_2" >
|
||||
<property name="text" >
|
||||
<string>Default network &timeout:</string>
|
||||
@ -143,7 +162,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="2" column="1" >
|
||||
<widget class="QSpinBox" name="timeout" >
|
||||
<property name="toolTip" >
|
||||
<string>Set the default timeout for network fetches (i.e. anytime we go out to the internet to get information)</string>
|
||||
@ -164,31 +183,78 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0" >
|
||||
<layout class="QHBoxLayout" >
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3" >
|
||||
<property name="text" >
|
||||
<string>&Priority for conversion jobs:</string>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<cstring>priority</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="priority" />
|
||||
</item>
|
||||
</layout>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2" >
|
||||
<property name="title" >
|
||||
<string>Toolbar</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout" >
|
||||
<item row="0" column="1" >
|
||||
<widget class="QComboBox" name="toolbar_button_size" >
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Large</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Medium</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Small</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" >
|
||||
<widget class="QLabel" name="label_4" >
|
||||
<property name="text" >
|
||||
<string>&Button size in toolbar</string>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<cstring>toolbar_button_size</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<widget class="QCheckBox" name="show_toolbar_text" >
|
||||
<property name="text" >
|
||||
<string>Show &text in toolbar buttons</string>
|
||||
</property>
|
||||
<property name="checked" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0" >
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox" >
|
||||
<property name="title" >
|
||||
<string>Select visible &columns in library view</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="_4" >
|
||||
<item row="0" column="0" >
|
||||
<widget class="QListWidget" name="columns" >
|
||||
<property name="selectionMode" >
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="dirs_box" >
|
||||
<property name="title" >
|
||||
<string>Frequently used directories</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<layout class="QGridLayout" name="_5" >
|
||||
<item row="0" column="0" >
|
||||
<layout class="QHBoxLayout" >
|
||||
<layout class="QHBoxLayout" name="_6" >
|
||||
<item>
|
||||
<widget class="QListWidget" name="directory_list" >
|
||||
<property name="alternatingRowColors" >
|
||||
@ -203,7 +269,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" >
|
||||
<layout class="QVBoxLayout" name="_7" >
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
@ -278,83 +344,6 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0" >
|
||||
<size>
|
||||
<width>392</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="5" column="0" >
|
||||
<widget class="QGroupBox" name="groupBox" >
|
||||
<property name="title" >
|
||||
<string>Select visible &columns in library view</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<item row="0" column="0" >
|
||||
<widget class="QListWidget" name="columns" >
|
||||
<property name="selectionMode" >
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" >
|
||||
<widget class="QGroupBox" name="groupBox_2" >
|
||||
<property name="title" >
|
||||
<string>Toolbar</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout" >
|
||||
<item row="0" column="1" >
|
||||
<widget class="QComboBox" name="toolbar_button_size" >
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Large</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Medium</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Small</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" >
|
||||
<widget class="QLabel" name="label_4" >
|
||||
<property name="text" >
|
||||
<string>&Button size in toolbar</string>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<cstring>toolbar_button_size</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<widget class="QCheckBox" name="show_toolbar_text" >
|
||||
<property name="text" >
|
||||
<string>Show &text in toolbar buttons</string>
|
||||
</property>
|
||||
<property name="checked" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_2" >
|
||||
@ -362,8 +351,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>583</width>
|
||||
<height>625</height>
|
||||
<width>595</width>
|
||||
<height>638</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
|
@ -150,9 +150,13 @@ class BooksModel(QAbstractTableModel):
|
||||
''' Return list indices of all cells in index.row()'''
|
||||
return [ self.index(index.row(), c) for c in range(self.columnCount(None))]
|
||||
|
||||
def save_to_disk(self, rows, path, single_dir=False):
|
||||
def save_to_disk(self, rows, path, single_dir=False, single_format=None):
|
||||
rows = [row.row() for row in rows]
|
||||
self.db.export_to_dir(path, rows, self.sorted_on[0] == 1, single_dir=single_dir)
|
||||
if single_format is None:
|
||||
return self.db.export_to_dir(path, rows, self.sorted_on[0] == 1, single_dir=single_dir)
|
||||
else:
|
||||
return self.db.export_single_format_to_dir(path, rows, single_format)
|
||||
|
||||
|
||||
def delete_books(self, indices):
|
||||
ids = [ self.id(i) for i in indices ]
|
||||
|
@ -136,6 +136,7 @@ class Main(MainWindow, Ui_MainWindow):
|
||||
self.save_menu = QMenu()
|
||||
self.save_menu.addAction(_('Save to disk'))
|
||||
self.save_menu.addAction(_('Save to disk in a single directory'))
|
||||
self.save_menu.addAction(_('Save only %s format to disk')%Settings().get('save to disk single format', 'lrf').upper())
|
||||
|
||||
self.view_menu = QMenu()
|
||||
self.view_menu.addAction(_('View'))
|
||||
@ -144,6 +145,7 @@ class Main(MainWindow, Ui_MainWindow):
|
||||
QObject.connect(self.action_save, SIGNAL("triggered(bool)"), self.save_to_disk)
|
||||
QObject.connect(self.save_menu.actions()[0], SIGNAL("triggered(bool)"), self.save_to_disk)
|
||||
QObject.connect(self.save_menu.actions()[1], SIGNAL("triggered(bool)"), self.save_to_single_dir)
|
||||
QObject.connect(self.save_menu.actions()[2], SIGNAL("triggered(bool)"), self.save_single_format_to_disk)
|
||||
QObject.connect(self.action_view, SIGNAL("triggered(bool)"), self.view_book)
|
||||
QObject.connect(self.view_menu.actions()[0], SIGNAL("triggered(bool)"), self.view_book)
|
||||
QObject.connect(self.view_menu.actions()[1], SIGNAL("triggered(bool)"), self.view_specific_format)
|
||||
@ -662,20 +664,32 @@ class Main(MainWindow, Ui_MainWindow):
|
||||
############################################################################
|
||||
|
||||
############################## Save to disk ################################
|
||||
def save_single_format_to_disk(self, checked):
|
||||
self.save_to_disk(checked, True, Settings().get('save to disk single format', 'lrf'))
|
||||
|
||||
def save_to_single_dir(self, checked):
|
||||
self.save_to_disk(checked, True)
|
||||
|
||||
def save_to_disk(self, checked, single_dir=False):
|
||||
def save_to_disk(self, checked, single_dir=False, single_format=None):
|
||||
rows = self.current_view().selectionModel().selectedRows()
|
||||
if not rows or len(rows) == 0:
|
||||
d = error_dialog(self, _('Cannot save to disk'), _('No books selected'))
|
||||
d.exec_()
|
||||
return
|
||||
|
||||
dir = choose_dir(self, 'save to disk dialog', ('Choose destination directory'))
|
||||
if not dir:
|
||||
return
|
||||
if self.current_view() == self.library_view:
|
||||
self.current_view().model().save_to_disk(rows, dir, single_dir=single_dir)
|
||||
failures = self.current_view().model().save_to_disk(rows, dir,
|
||||
single_dir=single_dir, single_format=single_format)
|
||||
if failures and single_format is not None:
|
||||
msg = _('<p>Could not save the following books to disk, because the %s format is not available for them:<ul>')%single_format.upper()
|
||||
for f in failures:
|
||||
msg += '<li>%s</li>'%f[1]
|
||||
msg += '</ul>'
|
||||
warning_dialog(self, _('Could not save some ebooks'), msg).exec_()
|
||||
QDesktopServices.openUrl(QUrl('file:'+dir))
|
||||
else:
|
||||
paths = self.current_view().model().paths(rows)
|
||||
self.job_manager.run_device_job(self.books_saved,
|
||||
|
@ -1549,6 +1549,25 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE;
|
||||
duplicates.extend(res)
|
||||
return duplicates
|
||||
|
||||
def export_single_format_to_dir(self, dir, indices, format, index_is_id=False):
|
||||
if not index_is_id:
|
||||
indices = map(self.id, indices)
|
||||
failures = []
|
||||
for id in indices:
|
||||
try:
|
||||
data = self.format(id, format, index_is_id=True)
|
||||
except:
|
||||
failures.append((id, self.title(id, index_is_id=True)))
|
||||
title = self.title(id, index_is_id=True)
|
||||
au = self.authors(id, index_is_id=True)
|
||||
if not au:
|
||||
au = _('Unknown')
|
||||
fname = '%s - %s.%s'%(title, au, format.lower())
|
||||
fname = sanitize_file_name(fname)
|
||||
open(os.path.join(dir, fname), 'wb').write(data)
|
||||
return failures
|
||||
|
||||
|
||||
|
||||
class SearchToken(object):
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user