mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Merge from trunk
This commit is contained in:
commit
1b985a67b4
@ -30,3 +30,4 @@ nbproject/
|
||||
.project
|
||||
.pydevproject
|
||||
.settings/
|
||||
*.DS_Store
|
||||
|
36
recipes/korea_herald.recipe
Normal file
36
recipes/korea_herald.recipe
Normal file
@ -0,0 +1,36 @@
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2011, Seongkyoun Yoo <Seongkyoun.yoo at gmail.com>'
|
||||
'''
|
||||
Profile to download KoreaHerald
|
||||
'''
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class KoreaHerald(BasicNewsRecipe):
|
||||
title = u'KoreaHerald'
|
||||
language = 'en'
|
||||
description = u'Korea Herald News articles'
|
||||
__author__ = 'Seongkyoun Yoo'
|
||||
oldest_article = 10
|
||||
recursions = 3
|
||||
max_articles_per_feed = 10
|
||||
no_stylesheets = True
|
||||
keep_only_tags = [
|
||||
dict(id=['contentLeft', '_article'])
|
||||
]
|
||||
|
||||
remove_tags = [
|
||||
dict(name='iframe'),
|
||||
dict(name='div', attrs={'class':['left','htit2', 'navigation','banner_txt','banner_img']}),
|
||||
dict(name='ul', attrs={'class':['link_icon', 'flow_icon','detailTextAD110113']}),
|
||||
]
|
||||
|
||||
feeds = [
|
||||
('All News','http://www.koreaherald.com/rss/020000000000.xml'),
|
||||
('National','http://www.koreaherald.com/rss/020100000000.xml'),
|
||||
('Business','http://www.koreaherald.com/rss/020200000000.xml'),
|
||||
('Life&Style','http://www.koreaherald.com/rss/020300000000.xml'),
|
||||
('Entertainment','http://www.koreaherald.com/rss/020400000000.xml'),
|
||||
('Sports','http://www.koreaherald.com/rss/020500000000.xml'),
|
||||
('Opinion','http://www.koreaherald.com/rss/020600000000.xml'),
|
||||
('English Cafe','http://www.koreaherald.com/rss/021000000000.xml'),
|
||||
]
|
@ -449,7 +449,7 @@ class CatalogPlugin(Plugin): # {{{
|
||||
['author_sort','authors','comments','cover','formats',
|
||||
'id','isbn','ondevice','pubdate','publisher','rating',
|
||||
'series_index','series','size','tags','timestamp',
|
||||
'title','uuid'])
|
||||
'title_sort','title','uuid'])
|
||||
all_custom_fields = set(db.custom_field_keys())
|
||||
all_fields = all_std_fields.union(all_custom_fields)
|
||||
|
||||
|
@ -68,9 +68,9 @@ class USER_DEFINED(USBMS):
|
||||
'is prepended to any send_to_device template') + '</p>',
|
||||
]
|
||||
EXTRA_CUSTOMIZATION_DEFAULT = [
|
||||
'0x0000',
|
||||
'0x0000',
|
||||
'0x0000',
|
||||
'0xffff',
|
||||
'0xffff',
|
||||
'0xffff',
|
||||
None,
|
||||
'',
|
||||
'',
|
||||
|
@ -403,7 +403,7 @@ def identify(log, abort, # {{{
|
||||
result.identify_plugin = plugin
|
||||
if msprefs['txt_comments']:
|
||||
if plugin.has_html_comments and result.comments:
|
||||
result.comments = html2text(r.comments)
|
||||
result.comments = html2text(result.comments)
|
||||
|
||||
log('The identify phase took %.2f seconds'%(time.time() - start_time))
|
||||
log('The longest time (%f) was taken by:'%longest, lp)
|
||||
|
@ -439,6 +439,7 @@ def populate_metadata_page(layout, db, book_id, bulk=False, two_column=False, pa
|
||||
w = widget_factory(dt, col)
|
||||
ans.append(w)
|
||||
for c in range(0, len(w.widgets), 2):
|
||||
w.widgets[c].setWordWrap(True)
|
||||
w.widgets[c].setBuddy(w.widgets[c+1])
|
||||
layout.addWidget(w.widgets[c], row, column)
|
||||
layout.addWidget(w.widgets[c+1], row, column+1)
|
||||
|
@ -10,7 +10,7 @@ __docformat__ = 'restructuredtext en'
|
||||
import textwrap, re, os
|
||||
|
||||
from PyQt4.Qt import (Qt, QDateEdit, QDate, pyqtSignal, QMessageBox,
|
||||
QIcon, QToolButton, QWidget, QLabel, QGridLayout,
|
||||
QIcon, QToolButton, QWidget, QLabel, QGridLayout, QApplication,
|
||||
QDoubleSpinBox, QListWidgetItem, QSize, QPixmap,
|
||||
QPushButton, QSpinBox, QLineEdit, QSizePolicy)
|
||||
|
||||
@ -1037,6 +1037,13 @@ class IdentifiersEdit(QLineEdit): # {{{
|
||||
self.setToolTip(tt+extra)
|
||||
self.setStyleSheet('QLineEdit { background-color: %s }'%col)
|
||||
|
||||
def paste_isbn(self):
|
||||
text = unicode(QApplication.clipboard().text()).strip()
|
||||
if text:
|
||||
vals = self.current_val
|
||||
vals['isbn'] = text
|
||||
self.current_val = vals
|
||||
|
||||
# }}}
|
||||
|
||||
class PublisherEdit(MultiCompleteComboBox): # {{{
|
||||
|
@ -69,7 +69,9 @@ class MetadataSingleDialogBase(ResizableDialog):
|
||||
self.setLayout(self.l)
|
||||
self.l.setMargin(0)
|
||||
self.l.addWidget(self.scroll_area)
|
||||
self.l.addWidget(self.button_box)
|
||||
ll = self.button_box_layout = QHBoxLayout()
|
||||
self.l.addLayout(ll)
|
||||
ll.addWidget(self.button_box)
|
||||
|
||||
self.setWindowIcon(QIcon(I('edit_input.png')))
|
||||
self.setWindowTitle(_('Edit Metadata'))
|
||||
@ -125,6 +127,13 @@ class MetadataSingleDialogBase(ResizableDialog):
|
||||
'Swap the author and title'))
|
||||
self.swap_title_author_button.clicked.connect(self.swap_title_author)
|
||||
|
||||
self.manage_authors_button = QToolButton(self)
|
||||
self.manage_authors_button.setIcon(QIcon(I('user_profile.png')))
|
||||
self.manage_authors_button.setToolTip('<p>' + _(
|
||||
'Manage authors. Use to rename authors and correct '
|
||||
'individual author\'s sort values') + '</p>')
|
||||
self.manage_authors_button.clicked.connect(self.authors.manage_authors)
|
||||
|
||||
self.series = SeriesEdit(self)
|
||||
self.remove_unused_series_button = QToolButton(self)
|
||||
self.remove_unused_series_button.setToolTip(
|
||||
@ -161,6 +170,12 @@ class MetadataSingleDialogBase(ResizableDialog):
|
||||
self.clear_identifiers_button = QToolButton(self)
|
||||
self.clear_identifiers_button.setIcon(QIcon(I('trash.png')))
|
||||
self.clear_identifiers_button.clicked.connect(self.identifiers.clear)
|
||||
self.paste_isbn_button = QToolButton(self)
|
||||
self.paste_isbn_button.setToolTip('<p>' +
|
||||
_('Paste the contents of the clipboard into the '
|
||||
'identifiers box prefixed with isbn:') + '</p>')
|
||||
self.paste_isbn_button.setIcon(QIcon(I('edit-paste.png')))
|
||||
self.paste_isbn_button.clicked.connect(self.identifiers.paste_isbn)
|
||||
|
||||
self.publisher = PublisherEdit(self)
|
||||
self.basic_metadata_widgets.append(self.publisher)
|
||||
@ -499,7 +514,8 @@ class MetadataSingleDialog(MetadataSingleDialogBase): # {{{
|
||||
sto(one, two)
|
||||
sto(two, three)
|
||||
|
||||
tl.addWidget(self.swap_title_author_button, 0, 0, 2, 1)
|
||||
tl.addWidget(self.swap_title_author_button, 0, 0, 1, 1)
|
||||
tl.addWidget(self.manage_authors_button, 1, 0, 1, 1)
|
||||
|
||||
create_row(0, self.title, self.deduce_title_sort_button, self.title_sort)
|
||||
sto(self.title_sort, self.authors)
|
||||
@ -508,6 +524,7 @@ class MetadataSingleDialog(MetadataSingleDialogBase): # {{{
|
||||
create_row(2, self.series, self.remove_unused_series_button,
|
||||
self.series_index, icon='trash.png')
|
||||
sto(self.series_index, self.swap_title_author_button)
|
||||
sto(self.swap_title_author_button, self.manage_authors_button)
|
||||
|
||||
tl.addWidget(self.formats_manager, 0, 6, 3, 1)
|
||||
|
||||
@ -518,7 +535,7 @@ class MetadataSingleDialog(MetadataSingleDialogBase): # {{{
|
||||
self.tabs[0].gb = gb = QGroupBox(_('Change cover'), self)
|
||||
gb.l = l = QGridLayout()
|
||||
gb.setLayout(l)
|
||||
sto(self.swap_title_author_button, self.cover.buttons[0])
|
||||
sto(self.manage_authors_button, self.cover.buttons[0])
|
||||
for i, b in enumerate(self.cover.buttons[:3]):
|
||||
l.addWidget(b, 0, i, 1, 1)
|
||||
sto(b, self.cover.buttons[i+1])
|
||||
@ -532,10 +549,16 @@ class MetadataSingleDialog(MetadataSingleDialogBase): # {{{
|
||||
w.setLayout(w.l)
|
||||
l.setMargin(0)
|
||||
self.splitter.addWidget(w)
|
||||
def create_row2(row, widget, button=None):
|
||||
def create_row2(row, widget, button=None, front_button=None):
|
||||
row += 1
|
||||
ql = BuddyLabel(widget)
|
||||
l.addWidget(ql, row, 0, 1, 1)
|
||||
if front_button:
|
||||
ltl = QHBoxLayout()
|
||||
ltl.addWidget(front_button)
|
||||
ltl.addWidget(ql)
|
||||
l.addLayout(ltl, row, 0, 1, 1)
|
||||
else:
|
||||
l.addWidget(ql, row, 0, 1, 1)
|
||||
l.addWidget(widget, row, 1, 1, 2 if button is None else 1)
|
||||
if button is not None:
|
||||
l.addWidget(button, row, 2, 1, 1)
|
||||
@ -550,8 +573,10 @@ class MetadataSingleDialog(MetadataSingleDialogBase): # {{{
|
||||
create_row2(1, self.rating)
|
||||
sto(self.rating, self.tags)
|
||||
create_row2(2, self.tags, self.tags_editor_button)
|
||||
sto(self.tags_editor_button, self.identifiers)
|
||||
create_row2(3, self.identifiers, self.clear_identifiers_button)
|
||||
sto(self.tags_editor_button, self.paste_isbn_button)
|
||||
sto(self.paste_isbn_button, self.identifiers)
|
||||
create_row2(3, self.identifiers, self.clear_identifiers_button,
|
||||
front_button=self.paste_isbn_button)
|
||||
sto(self.clear_identifiers_button, self.timestamp)
|
||||
create_row2(4, self.timestamp, self.timestamp.clear_button)
|
||||
sto(self.timestamp.clear_button, self.pubdate)
|
||||
@ -624,13 +649,13 @@ class MetadataSingleDialogAlt1(MetadataSingleDialogBase): # {{{
|
||||
self.tabs[0].l.addWidget(gb, 0, 0, 1, 1)
|
||||
gb.setLayout(tl)
|
||||
|
||||
self.button_box.addButton(self.fetch_metadata_button,
|
||||
QDialogButtonBox.ActionRole)
|
||||
self.button_box_layout.insertWidget(0, self.fetch_metadata_button)
|
||||
self.config_metadata_button.setToolButtonStyle(Qt.ToolButtonTextOnly)
|
||||
self.config_metadata_button.setText(_('Configure metadata downloading'))
|
||||
self.button_box.addButton(self.config_metadata_button,
|
||||
QDialogButtonBox.ActionRole)
|
||||
sto(self.button_box, self.title)
|
||||
self.button_box_layout.insertWidget(1, self.config_metadata_button)
|
||||
sto(self.button_box, self.fetch_metadata_button)
|
||||
sto(self.fetch_metadata_button, self.config_metadata_button)
|
||||
sto(self.config_metadata_button, self.title)
|
||||
|
||||
def create_row(row, widget, tab_to, button=None, icon=None, span=1):
|
||||
ql = BuddyLabel(widget)
|
||||
@ -648,6 +673,8 @@ class MetadataSingleDialogAlt1(MetadataSingleDialogBase): # {{{
|
||||
sto(widget, tab_to)
|
||||
|
||||
tl.addWidget(self.swap_title_author_button, 0, 0, 2, 1)
|
||||
tl.addWidget(self.manage_authors_button, 2, 0, 1, 1)
|
||||
tl.addWidget(self.paste_isbn_button, 11, 0, 1, 1)
|
||||
|
||||
create_row(0, self.title, self.title_sort,
|
||||
button=self.deduce_title_sort_button, span=2,
|
||||
@ -669,6 +696,9 @@ class MetadataSingleDialogAlt1(MetadataSingleDialogBase): # {{{
|
||||
button=self.timestamp.clear_button, icon='trash.png')
|
||||
create_row(11, self.identifiers, self.comments,
|
||||
button=self.clear_identifiers_button, icon='trash.png')
|
||||
sto(self.clear_identifiers_button, self.swap_title_author_button)
|
||||
sto(self.swap_title_author_button, self.manage_authors_button)
|
||||
sto(self.manage_authors_button, self.paste_isbn_button)
|
||||
tl.addItem(QSpacerItem(1, 1, QSizePolicy.Fixed, QSizePolicy.Expanding),
|
||||
12, 1, 1 ,1)
|
||||
|
||||
@ -708,7 +738,6 @@ class MetadataSingleDialogAlt1(MetadataSingleDialogBase): # {{{
|
||||
gb = QGroupBox(_('Change cover'), tab1)
|
||||
l = QGridLayout()
|
||||
gb.setLayout(l)
|
||||
sto(self.swap_title_author_button, self.cover.buttons[0])
|
||||
for i, b in enumerate(self.cover.buttons[:3]):
|
||||
l.addWidget(b, 0, i, 1, 1)
|
||||
sto(b, self.cover.buttons[i+1])
|
||||
@ -756,13 +785,13 @@ class MetadataSingleDialogAlt2(MetadataSingleDialogBase): # {{{
|
||||
l.addWidget(gb, 0, 0, 1, 1)
|
||||
gb.setLayout(tl)
|
||||
|
||||
self.button_box.addButton(self.fetch_metadata_button,
|
||||
QDialogButtonBox.ActionRole)
|
||||
self.button_box_layout.insertWidget(0, self.fetch_metadata_button)
|
||||
self.config_metadata_button.setToolButtonStyle(Qt.ToolButtonTextOnly)
|
||||
self.config_metadata_button.setText(_('Configure metadata downloading'))
|
||||
self.button_box.addButton(self.config_metadata_button,
|
||||
QDialogButtonBox.ActionRole)
|
||||
sto(self.button_box, self.title)
|
||||
self.button_box_layout.insertWidget(1, self.config_metadata_button)
|
||||
sto(self.button_box, self.fetch_metadata_button)
|
||||
sto(self.fetch_metadata_button, self.config_metadata_button)
|
||||
sto(self.config_metadata_button, self.title)
|
||||
|
||||
def create_row(row, widget, tab_to, button=None, icon=None, span=1):
|
||||
ql = BuddyLabel(widget)
|
||||
@ -780,6 +809,8 @@ class MetadataSingleDialogAlt2(MetadataSingleDialogBase): # {{{
|
||||
sto(widget, tab_to)
|
||||
|
||||
tl.addWidget(self.swap_title_author_button, 0, 0, 2, 1)
|
||||
tl.addWidget(self.manage_authors_button, 2, 0, 2, 1)
|
||||
tl.addWidget(self.paste_isbn_button, 11, 0, 1, 1)
|
||||
|
||||
create_row(0, self.title, self.title_sort,
|
||||
button=self.deduce_title_sort_button, span=2,
|
||||
@ -801,6 +832,9 @@ class MetadataSingleDialogAlt2(MetadataSingleDialogBase): # {{{
|
||||
button=self.timestamp.clear_button, icon='trash.png')
|
||||
create_row(11, self.identifiers, self.comments,
|
||||
button=self.clear_identifiers_button, icon='trash.png')
|
||||
sto(self.clear_identifiers_button, self.swap_title_author_button)
|
||||
sto(self.swap_title_author_button, self.manage_authors_button)
|
||||
sto(self.manage_authors_button, self.paste_isbn_button)
|
||||
tl.addItem(QSpacerItem(1, 1, QSizePolicy.Fixed, QSizePolicy.Expanding),
|
||||
12, 1, 1 ,1)
|
||||
|
||||
@ -820,7 +854,7 @@ class MetadataSingleDialogAlt2(MetadataSingleDialogBase): # {{{
|
||||
l.addWidget(gb, 0, 1, 1, 1)
|
||||
sp = QSizePolicy()
|
||||
sp.setVerticalStretch(10)
|
||||
sp.setHorizontalPolicy(QSizePolicy.Fixed)
|
||||
sp.setHorizontalPolicy(QSizePolicy.Minimum)
|
||||
sp.setVerticalPolicy(QSizePolicy.Expanding)
|
||||
gb.setSizePolicy(sp)
|
||||
self.set_custom_metadata_tab_order()
|
||||
@ -842,7 +876,7 @@ class MetadataSingleDialogAlt2(MetadataSingleDialogBase): # {{{
|
||||
lb = QGridLayout()
|
||||
gb.setLayout(lb)
|
||||
lb.addWidget(self.cover, 0, 0, 1, 3, alignment=Qt.AlignCenter)
|
||||
sto(self.clear_identifiers_button, self.cover.buttons[0])
|
||||
sto(self.manage_authors_button, self.cover.buttons[0])
|
||||
for i, b in enumerate(self.cover.buttons[:3]):
|
||||
lb.addWidget(b, 1, i, 1, 1)
|
||||
sto(b, self.cover.buttons[i+1])
|
||||
|
@ -27,7 +27,7 @@ from calibre.utils.logging import default_log as log
|
||||
from calibre.utils.magick.draw import thumbnail
|
||||
from calibre.utils.zipfile import ZipFile, ZipInfo
|
||||
|
||||
FIELDS = ['all', 'title', 'author_sort', 'authors', 'comments',
|
||||
FIELDS = ['all', 'title', 'title_sort', 'author_sort', 'authors', 'comments',
|
||||
'cover', 'formats','id', 'isbn', 'ondevice', 'pubdate', 'publisher',
|
||||
'rating', 'series_index', 'series', 'size', 'tags', 'timestamp', 'uuid']
|
||||
|
||||
@ -66,7 +66,7 @@ class CSV_XML(CatalogPlugin): # {{{
|
||||
dest = 'sort_by',
|
||||
action = None,
|
||||
help = _('Output field to sort on.\n'
|
||||
'Available fields: author_sort, id, rating, size, timestamp, title.\n'
|
||||
'Available fields: author_sort, id, rating, size, timestamp, title_sort\n'
|
||||
"Default: '%default'\n"
|
||||
"Applies to: CSV, XML output formats"))]
|
||||
|
||||
@ -76,7 +76,7 @@ class CSV_XML(CatalogPlugin): # {{{
|
||||
|
||||
if opts.verbose:
|
||||
opts_dict = vars(opts)
|
||||
log("%s(): Generating %s" % (self.name,self.fmt))
|
||||
log("%s(): Generating %s" % (self.name,self.fmt.upper()))
|
||||
if opts.connected_device['is_device_connected']:
|
||||
log(" connected_device: %s" % opts.connected_device['name'])
|
||||
if opts_dict['search_text']:
|
||||
@ -126,8 +126,11 @@ class CSV_XML(CatalogPlugin): # {{{
|
||||
for field in fields:
|
||||
if field.startswith('#'):
|
||||
item = db.get_field(entry['id'],field,index_is_id=True)
|
||||
elif field == 'title_sort':
|
||||
item = entry['sort']
|
||||
else:
|
||||
item = entry[field]
|
||||
|
||||
if item is None:
|
||||
outstr.append('""')
|
||||
continue
|
||||
@ -167,7 +170,7 @@ class CSV_XML(CatalogPlugin): # {{{
|
||||
item = getattr(E, field.replace('#','_'))(val)
|
||||
record.append(item)
|
||||
|
||||
for field in ('id', 'uuid', 'title', 'publisher', 'rating', 'size',
|
||||
for field in ('id', 'uuid', 'publisher', 'rating', 'size',
|
||||
'isbn','ondevice'):
|
||||
if field in fields:
|
||||
val = r[field]
|
||||
@ -178,6 +181,10 @@ class CSV_XML(CatalogPlugin): # {{{
|
||||
item = getattr(E, field)(val)
|
||||
record.append(item)
|
||||
|
||||
if 'title' in fields:
|
||||
title = E.title(r['title'], sort=r['sort'])
|
||||
record.append(title)
|
||||
|
||||
if 'authors' in fields:
|
||||
aus = E.authors(sort=r['author_sort'])
|
||||
for au in r['authors']:
|
||||
|
@ -3056,7 +3056,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
||||
'''
|
||||
if prefix is None:
|
||||
prefix = self.library_path
|
||||
FIELDS = set(['title', 'authors', 'author_sort', 'publisher', 'rating',
|
||||
FIELDS = set(['title', 'sort', 'authors', 'author_sort', 'publisher', 'rating',
|
||||
'timestamp', 'size', 'tags', 'comments', 'series', 'series_index',
|
||||
'uuid', 'pubdate', 'last_modified', 'identifiers'])
|
||||
for x in self.custom_column_num_map:
|
||||
|
Loading…
x
Reference in New Issue
Block a user