mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Merge with trunk
This commit is contained in:
commit
022e80568d
@ -251,8 +251,8 @@
|
|||||||
- title: Techcrunch and Pecat
|
- title: Techcrunch and Pecat
|
||||||
author: Darko Miletic
|
author: Darko Miletic
|
||||||
|
|
||||||
- title: Vio Mundo, IDG Now and Tojolaco
|
- title: "Vio Mundo, IDG Now! and Tojolaco"
|
||||||
author: Diniz Bortoletto
|
author: Diniz Bortolotto
|
||||||
|
|
||||||
- title: Geek and Poke, Automatiseringgids IT
|
- title: Geek and Poke, Automatiseringgids IT
|
||||||
author: DrMerry
|
author: DrMerry
|
||||||
|
28
recipes/escrevinhador.recipe
Normal file
28
recipes/escrevinhador.recipe
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class Escrevinhador(BasicNewsRecipe):
|
||||||
|
title = 'Blog Escrevinhador'
|
||||||
|
__author__ = 'Diniz Bortolotto'
|
||||||
|
description = 'Posts do Blog Escrevinhador'
|
||||||
|
publisher = 'Rodrigo Viana'
|
||||||
|
oldest_article = 5
|
||||||
|
max_articles_per_feed = 20
|
||||||
|
category = 'news, politics, Brazil'
|
||||||
|
language = 'pt_BR'
|
||||||
|
publication_type = 'news and politics portal'
|
||||||
|
use_embedded_content = False
|
||||||
|
no_stylesheets = True
|
||||||
|
remove_javascript = True
|
||||||
|
|
||||||
|
feeds = [(u'Blog Escrevinhador', u'http://www.rodrigovianna.com.br/feed')]
|
||||||
|
|
||||||
|
reverse_article_order = True
|
||||||
|
|
||||||
|
remove_tags_after = [dict(name='div', attrs={'class':'text'})]
|
||||||
|
|
||||||
|
remove_tags = [
|
||||||
|
dict(id='header'),
|
||||||
|
dict(name='p', attrs={'class':'tags'}),
|
||||||
|
dict(name='div', attrs={'class':'sociable'})
|
||||||
|
]
|
||||||
|
|
BIN
resources/images/mimetypes/xps.png
Executable file
BIN
resources/images/mimetypes/xps.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
@ -6,6 +6,7 @@ Created on 15 May 2010
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from calibre.devices.usbms.driver import USBMS, BookList
|
from calibre.devices.usbms.driver import USBMS, BookList
|
||||||
|
from calibre.ebooks import BOOK_EXTENSIONS
|
||||||
|
|
||||||
# This class is added to the standard device plugin chain, so that it can
|
# This class is added to the standard device plugin chain, so that it can
|
||||||
# be configured. It has invalid vendor_id etc, so it will never match a
|
# be configured. It has invalid vendor_id etc, so it will never match a
|
||||||
@ -16,8 +17,8 @@ class FOLDER_DEVICE_FOR_CONFIG(USBMS):
|
|||||||
description = _('Use an arbitrary folder as a device.')
|
description = _('Use an arbitrary folder as a device.')
|
||||||
author = 'John Schember/Charles Haley'
|
author = 'John Schember/Charles Haley'
|
||||||
supported_platforms = ['windows', 'osx', 'linux']
|
supported_platforms = ['windows', 'osx', 'linux']
|
||||||
FORMATS = ['epub', 'fb2', 'mobi', 'azw', 'lrf', 'tcr', 'pmlz', 'lit',
|
FORMATS = list(BOOK_EXTENSIONS)
|
||||||
'rtf', 'rb', 'pdf', 'oeb', 'txt', 'pdb', 'prc']
|
|
||||||
VENDOR_ID = [0xffff]
|
VENDOR_ID = [0xffff]
|
||||||
PRODUCT_ID = [0xffff]
|
PRODUCT_ID = [0xffff]
|
||||||
BCD = [0xffff]
|
BCD = [0xffff]
|
||||||
|
@ -67,10 +67,6 @@ def _metadata_from_formats(formats, force_read_metadata=False, pattern=None):
|
|||||||
|
|
||||||
return mi
|
return mi
|
||||||
|
|
||||||
def is_recipe(filename):
|
|
||||||
return filename.startswith('calibre') and \
|
|
||||||
filename.rpartition('.')[0].endswith('_recipe_out')
|
|
||||||
|
|
||||||
def get_metadata(stream, stream_type='lrf', use_libprs_metadata=False,
|
def get_metadata(stream, stream_type='lrf', use_libprs_metadata=False,
|
||||||
force_read_metadata=False, pattern=None):
|
force_read_metadata=False, pattern=None):
|
||||||
pos = 0
|
pos = 0
|
||||||
@ -106,7 +102,7 @@ def _get_metadata(stream, stream_type, use_libprs_metadata,
|
|||||||
mi = MetaInformation(None, None)
|
mi = MetaInformation(None, None)
|
||||||
name = os.path.basename(getattr(stream, 'name', ''))
|
name = os.path.basename(getattr(stream, 'name', ''))
|
||||||
base = metadata_from_filename(name, pat=pattern)
|
base = metadata_from_filename(name, pat=pattern)
|
||||||
if force_read_metadata or is_recipe(name) or prefs['read_file_metadata']:
|
if force_read_metadata or prefs['read_file_metadata']:
|
||||||
mi = get_file_type_metadata(stream, stream_type)
|
mi = get_file_type_metadata(stream, stream_type)
|
||||||
if base.title == os.path.splitext(name)[0] and \
|
if base.title == os.path.splitext(name)[0] and \
|
||||||
base.is_null('authors') and base.is_null('isbn'):
|
base.is_null('authors') and base.is_null('isbn'):
|
||||||
|
@ -425,6 +425,8 @@ class FileIconProvider(QFileIconProvider):
|
|||||||
'snb' : 'snb',
|
'snb' : 'snb',
|
||||||
'djv' : 'djvu',
|
'djv' : 'djvu',
|
||||||
'djvu' : 'djvu',
|
'djvu' : 'djvu',
|
||||||
|
'xps' : 'xps',
|
||||||
|
'oxps' : 'xps',
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -87,7 +87,7 @@ class Int(Base):
|
|||||||
self.widgets = [QLabel('&'+self.col_metadata['name']+':', parent),
|
self.widgets = [QLabel('&'+self.col_metadata['name']+':', parent),
|
||||||
QSpinBox(parent)]
|
QSpinBox(parent)]
|
||||||
w = self.widgets[1]
|
w = self.widgets[1]
|
||||||
w.setRange(-100, 100000000)
|
w.setRange(-1000000, 100000000)
|
||||||
w.setSpecialValueText(_('Undefined'))
|
w.setSpecialValueText(_('Undefined'))
|
||||||
w.setSingleStep(1)
|
w.setSingleStep(1)
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ class Float(Int):
|
|||||||
self.widgets = [QLabel('&'+self.col_metadata['name']+':', parent),
|
self.widgets = [QLabel('&'+self.col_metadata['name']+':', parent),
|
||||||
QDoubleSpinBox(parent)]
|
QDoubleSpinBox(parent)]
|
||||||
w = self.widgets[1]
|
w = self.widgets[1]
|
||||||
w.setRange(-100., float(100000000))
|
w.setRange(-1000000., float(100000000))
|
||||||
w.setDecimals(2)
|
w.setDecimals(2)
|
||||||
w.setSpecialValueText(_('Undefined'))
|
w.setSpecialValueText(_('Undefined'))
|
||||||
w.setSingleStep(1)
|
w.setSingleStep(1)
|
||||||
@ -300,7 +300,6 @@ class Series(Base):
|
|||||||
w = QDoubleSpinBox(parent)
|
w = QDoubleSpinBox(parent)
|
||||||
w.setRange(-100., float(100000000))
|
w.setRange(-100., float(100000000))
|
||||||
w.setDecimals(2)
|
w.setDecimals(2)
|
||||||
w.setSpecialValueText(_('Undefined'))
|
|
||||||
w.setSingleStep(1)
|
w.setSingleStep(1)
|
||||||
self.idx_widget=w
|
self.idx_widget=w
|
||||||
self.widgets.append(w)
|
self.widgets.append(w)
|
||||||
@ -605,7 +604,7 @@ class BulkInt(BulkBase):
|
|||||||
|
|
||||||
def setup_ui(self, parent):
|
def setup_ui(self, parent):
|
||||||
self.make_widgets(parent, QSpinBox)
|
self.make_widgets(parent, QSpinBox)
|
||||||
self.main_widget.setRange(-100, 100000000)
|
self.main_widget.setRange(-1000000, 100000000)
|
||||||
self.main_widget.setSpecialValueText(_('Undefined'))
|
self.main_widget.setSpecialValueText(_('Undefined'))
|
||||||
self.main_widget.setSingleStep(1)
|
self.main_widget.setSingleStep(1)
|
||||||
|
|
||||||
@ -627,7 +626,7 @@ class BulkFloat(BulkInt):
|
|||||||
|
|
||||||
def setup_ui(self, parent):
|
def setup_ui(self, parent):
|
||||||
self.make_widgets(parent, QDoubleSpinBox)
|
self.make_widgets(parent, QDoubleSpinBox)
|
||||||
self.main_widget.setRange(-100., float(100000000))
|
self.main_widget.setRange(-1000000., float(100000000))
|
||||||
self.main_widget.setDecimals(2)
|
self.main_widget.setDecimals(2)
|
||||||
self.main_widget.setSpecialValueText(_('Undefined'))
|
self.main_widget.setSpecialValueText(_('Undefined'))
|
||||||
self.main_widget.setSingleStep(1)
|
self.main_widget.setSingleStep(1)
|
||||||
|
@ -300,13 +300,13 @@ class CcNumberDelegate(QStyledItemDelegate): # {{{
|
|||||||
col = m.column_map[index.column()]
|
col = m.column_map[index.column()]
|
||||||
if m.custom_columns[col]['datatype'] == 'int':
|
if m.custom_columns[col]['datatype'] == 'int':
|
||||||
editor = QSpinBox(parent)
|
editor = QSpinBox(parent)
|
||||||
editor.setRange(-100, 100000000)
|
editor.setRange(-1000000, 100000000)
|
||||||
editor.setSpecialValueText(_('Undefined'))
|
editor.setSpecialValueText(_('Undefined'))
|
||||||
editor.setSingleStep(1)
|
editor.setSingleStep(1)
|
||||||
else:
|
else:
|
||||||
editor = QDoubleSpinBox(parent)
|
editor = QDoubleSpinBox(parent)
|
||||||
editor.setSpecialValueText(_('Undefined'))
|
editor.setSpecialValueText(_('Undefined'))
|
||||||
editor.setRange(-100., 100000000)
|
editor.setRange(-1000000., 100000000)
|
||||||
editor.setDecimals(2)
|
editor.setDecimals(2)
|
||||||
return editor
|
return editor
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ class BooksModel(QAbstractTableModel): # {{{
|
|||||||
'rating' : _('Rating'),
|
'rating' : _('Rating'),
|
||||||
'publisher' : _("Publisher"),
|
'publisher' : _("Publisher"),
|
||||||
'tags' : _("Tags"),
|
'tags' : _("Tags"),
|
||||||
'series' : _("Series"),
|
'series' : ngettext("Series", 'Series', 1),
|
||||||
'last_modified' : _('Modified'),
|
'last_modified' : _('Modified'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ from calibre.gui2 import error_dialog, question_dialog
|
|||||||
from calibre.gui2.preferences.save_template_ui import Ui_Form
|
from calibre.gui2.preferences.save_template_ui import Ui_Form
|
||||||
from calibre.library.save_to_disk import FORMAT_ARG_DESCS, preprocess_template
|
from calibre.library.save_to_disk import FORMAT_ARG_DESCS, preprocess_template
|
||||||
from calibre.utils.formatter import validation_formatter
|
from calibre.utils.formatter import validation_formatter
|
||||||
|
from calibre.gui2.dialogs.template_dialog import TemplateDialog
|
||||||
|
|
||||||
|
|
||||||
class SaveTemplate(QWidget, Ui_Form):
|
class SaveTemplate(QWidget, Ui_Form):
|
||||||
@ -40,6 +41,14 @@ class SaveTemplate(QWidget, Ui_Form):
|
|||||||
self.opt_template.editTextChanged.connect(self.changed)
|
self.opt_template.editTextChanged.connect(self.changed)
|
||||||
self.opt_template.currentIndexChanged.connect(self.changed)
|
self.opt_template.currentIndexChanged.connect(self.changed)
|
||||||
self.option_name = name
|
self.option_name = name
|
||||||
|
self.open_editor.clicked.connect(self.do_open_editor)
|
||||||
|
|
||||||
|
def do_open_editor(self):
|
||||||
|
t = TemplateDialog(self, self.opt_template.text())
|
||||||
|
t.setWindowTitle(_('Edit template'))
|
||||||
|
if t.exec_():
|
||||||
|
self.opt_template.set_value(t.rule[1])
|
||||||
|
|
||||||
|
|
||||||
def changed(self, *args):
|
def changed(self, *args):
|
||||||
self.changed_signal.emit()
|
self.changed_signal.emit()
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
<string>Save &template</string>
|
<string>Save &template</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0" colspan="2">
|
||||||
<widget class="QLabel" name="label_4">
|
<widget class="QLabel" name="label_4">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>By adjusting the template below, you can control what folders the files are saved in and what filenames they are given. You can use the / character to indicate sub-folders. Available metadata variables are described below. If a particular book does not have some metadata, the variable will be replaced by the empty string.</string>
|
<string>By adjusting the template below, you can control what folders the files are saved in and what filenames they are given. You can use the / character to indicate sub-folders. Available metadata variables are described below. If a particular book does not have some metadata, the variable will be replaced by the empty string.</string>
|
||||||
@ -30,18 +30,38 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0" colspan="2">
|
||||||
<widget class="QLabel" name="label_5">
|
<widget class="QLabel" name="label_5">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Available variables:</string>
|
<string>Available variables:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="3" column="0" colspan="2">
|
||||||
<widget class="QTextBrowser" name="template_variables"/>
|
<widget class="QTextBrowser" name="template_variables"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="HistoryBox" name="opt_template"/>
|
<widget class="HistoryBox" name="opt_template">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<horstretch>10</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="sizeAdjustPolicy">
|
||||||
|
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
|
||||||
|
</property>
|
||||||
|
<property name="minimumContentsLength">
|
||||||
|
<number>40</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QPushButton" name="open_editor">
|
||||||
|
<property name="text">
|
||||||
|
<string>Template Editor</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -28,7 +28,7 @@ class OpenBooksStore(BasicStoreConfig, StorePlugin):
|
|||||||
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_item if detail_item else url)))
|
open_url(QUrl(url_slash_cleaner(detail_item if detail_item else url)))
|
||||||
else:
|
else:
|
||||||
d = WebStoreDialog(self.gui, self.url, parent, detail_item)
|
d = WebStoreDialog(self.gui, url, parent, detail_item)
|
||||||
d.setWindowTitle(self.name)
|
d.setWindowTitle(self.name)
|
||||||
d.set_tags(self.config.get('tags', ''))
|
d.set_tags(self.config.get('tags', ''))
|
||||||
d.exec_()
|
d.exec_()
|
||||||
|
@ -3024,7 +3024,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
format = os.path.splitext(path)[1][1:].lower()
|
format = os.path.splitext(path)[1][1:].lower()
|
||||||
stream = path if hasattr(path, 'read') else lopen(path, 'rb')
|
stream = path if hasattr(path, 'read') else lopen(path, 'rb')
|
||||||
stream.seek(0)
|
stream.seek(0)
|
||||||
mi = get_metadata(stream, format, use_libprs_metadata=False)
|
mi = get_metadata(stream, format, use_libprs_metadata=False,
|
||||||
|
force_read_metadata=True)
|
||||||
stream.seek(0)
|
stream.seek(0)
|
||||||
if mi.series_index is None:
|
if mi.series_index is None:
|
||||||
mi.series_index = self.get_next_series_num_for(mi.series)
|
mi.series_index = self.get_next_series_num_for(mi.series)
|
||||||
|
@ -296,8 +296,8 @@ def do_save_book_to_disk(id_, mi, cover, plugboards,
|
|||||||
replace_whitespace=opts.replace_whitespace, safe_format=False)
|
replace_whitespace=opts.replace_whitespace, safe_format=False)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
raise ValueError(_('Failed to calculate path for '
|
raise ValueError(_('Failed to calculate path for '
|
||||||
'save to disk. Template: %s\n'
|
'save to disk. Template: %(templ)s\n'
|
||||||
'Error: %s'%(opts.template, e)))
|
'Error: %(err)s')%dict(templ=opts.template, err=e))
|
||||||
if opts.single_dir:
|
if opts.single_dir:
|
||||||
components = components[-1:]
|
components = components[-1:]
|
||||||
if not components:
|
if not components:
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user