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
05e9dc65d1
@ -21,14 +21,19 @@ class Fronda(BasicNewsRecipe):
|
||||
|
||||
feeds = [(u'Infformacje', u'http://fronda.pl/news/feed')]
|
||||
|
||||
keep_only_tags = [dict(name='h1', attrs={'class':'big'}),
|
||||
dict(name='ul', attrs={'class':'about clear'}),
|
||||
dict(name='div', attrs={'class':'content'})]
|
||||
keep_only_tags = [dict(name='h2', attrs={'class':'news_title'}),
|
||||
dict(name='div', attrs={'class':'naglowek_tresc'}),
|
||||
dict(name='div', attrs={'id':'czytaj'}) ]
|
||||
|
||||
remove_tags = [dict(name='a', attrs={'class':'print'})]
|
||||
|
||||
preprocess_regexps = [
|
||||
(re.compile(i[0], re.IGNORECASE | re.DOTALL), i[1]) for i in
|
||||
[ (r'<a href="#" class="print">Drukuj</a>', lambda match: ''),
|
||||
(r'<p><a href="http://fronda.pl/sklepy">.*</a></p>', lambda match: ''),
|
||||
[ (r'<p><a href="http://fronda.pl/sklepy">.*</a></p>', lambda match: ''),
|
||||
(r'<p><a href="http://fronda.pl/pasaz">.*</a></p>', lambda match: ''),
|
||||
(r'<h3><strong>W.* lektury.*</a></p></div>', lambda match: '</div>'),
|
||||
(r'<h3>Zobacz t.*?</div>', lambda match: '</div>') ]
|
||||
(r'<h3>Zobacz t.*?</div>', lambda match: '</div>'),
|
||||
(r'<p[^>]*> </p>', lambda match: ''),
|
||||
(r'<p><span style=".*?"><br /></span></p> ', lambda match: ''),
|
||||
(r'<a style=\'float:right;margin-top:3px;\' href="http://www.facebook.com/share.php?.*?</a>', lambda match: '')]
|
||||
]
|
||||
|
BIN
recipes/icons/rzeczpospolita.png
Normal file
BIN
recipes/icons/rzeczpospolita.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
BIN
recipes/icons/ziuaveche.png
Normal file
BIN
recipes/icons/ziuaveche.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 554 B |
@ -2,7 +2,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class RzeczpospolitaRecipe(BasicNewsRecipe):
|
||||
__license__ = 'GPL v3'
|
||||
__author__ = 'kwetal'
|
||||
__author__ = u'kwetal and Tomasz Dlugosz'
|
||||
language = 'pl'
|
||||
version = 1
|
||||
|
||||
@ -38,6 +38,8 @@ class RzeczpospolitaRecipe(BasicNewsRecipe):
|
||||
remove_tags.append(dict(name = 'div', attrs = {'class' : 'clr'}))
|
||||
remove_tags.append(dict(name = 'div', attrs = {'id' : 'share_bottom'}))
|
||||
remove_tags.append(dict(name = 'div', attrs = {'id' : 'copyright_law'}))
|
||||
remove_tags.append(dict(name = 'div', attrs = {'class' : 'more'}))
|
||||
remove_tags.append(dict(name = 'div', attrs = {'class' : 'editorPicks'}))
|
||||
|
||||
extra_css = '''
|
||||
body {font-family: verdana, arial, helvetica, geneva, sans-serif ;}
|
||||
@ -48,6 +50,13 @@ class RzeczpospolitaRecipe(BasicNewsRecipe):
|
||||
.fot{font-size: x-small; color: #666666;}
|
||||
'''
|
||||
|
||||
def skip_ad_pages(self, soup):
|
||||
if ('advertisement' in soup.find('title').string.lower()):
|
||||
href = soup.find('a').get('href')
|
||||
return self.index_to_soup(href, raw=True)
|
||||
else:
|
||||
return None
|
||||
|
||||
def print_version(self, url):
|
||||
start, sep, rest = url.rpartition('/')
|
||||
forget, sep, index = rest.rpartition(',')
|
||||
|
@ -1,17 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2009, Gerhard Aigner <gerhard.aigner at gmail.com>'
|
||||
|
||||
|
||||
import re
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class TelepolisNews(BasicNewsRecipe):
|
||||
title = u'Telepolis (News+Artikel)'
|
||||
__author__ = 'Gerhard Aigner'
|
||||
__author__ = 'syntaxis'
|
||||
publisher = 'Heise Zeitschriften Verlag GmbH & Co KG'
|
||||
description = 'News from telepolis'
|
||||
description = 'News from Telepolis'
|
||||
category = 'news'
|
||||
oldest_article = 7
|
||||
max_articles_per_feed = 100
|
||||
@ -20,14 +15,19 @@ class TelepolisNews(BasicNewsRecipe):
|
||||
encoding = "utf-8"
|
||||
language = 'de'
|
||||
|
||||
use_embedded_content =False
|
||||
|
||||
remove_empty_feeds = True
|
||||
|
||||
preprocess_regexps = [(re.compile(r'<a[^>]*>', re.DOTALL|re.IGNORECASE), lambda match: ''),
|
||||
(re.compile(r'</a>', re.DOTALL|re.IGNORECASE), lambda match: ''),]
|
||||
|
||||
keep_only_tags = [dict(name = 'td',attrs={'class':'bloghead'}),dict(name = 'td',attrs={'class':'blogfliess'})]
|
||||
remove_tags = [dict(name='img'), dict(name='td',attrs={'class':'blogbottom'}), dict(name='td',attrs={'class':'forum'})]
|
||||
|
||||
keep_only_tags = [dict(name = 'div',attrs={'class':'head'}),dict(name = 'div',attrs={'class':'leftbox'}),dict(name='td',attrs={'class':'strict'})]
|
||||
remove_tags = [ dict(name='td',attrs={'class':'blogbottom'}),
|
||||
dict(name='div',attrs={'class':'forum'}), dict(name='div',attrs={'class':'social'}),dict(name='div',attrs={'class':'blog-letter p-news'}),
|
||||
dict(name='div',attrs={'class':'blog-sub'}),dict(name='div',attrs={'class':'version-div'}),dict(name='div',attrs={'id':'breadcrumb'})
|
||||
,dict(attrs={'class':'tp-url'}),dict(attrs={'class':'blog-name entry_'}) ]
|
||||
|
||||
remove_tags_after = [dict(name='span', attrs={'class':['breadcrumb']})]
|
||||
|
||||
|
||||
feeds = [(u'News', u'http://www.heise.de/tp/news-atom.xml')]
|
||||
|
||||
@ -39,15 +39,8 @@ class TelepolisNews(BasicNewsRecipe):
|
||||
|
||||
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
|
||||
|
||||
def get_article_url(self, article):
|
||||
'''if the linked article is of kind artikel don't take it'''
|
||||
if (article.link.count('artikel') > 1) :
|
||||
return None
|
||||
return article.link
|
||||
|
||||
def preprocess_html(self, soup):
|
||||
mtag = '<meta http-equiv="Content-Type" content="text/html; charset=' + self.encoding + '">'
|
||||
soup.head.insert(0,mtag)
|
||||
return soup
|
||||
|
||||
|
||||
|
53
recipes/ziuaveche.recipe
Normal file
53
recipes/ziuaveche.recipe
Normal file
@ -0,0 +1,53 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = u'2011, Silviu Cotoar\u0103'
|
||||
'''
|
||||
ziuaveche.ro
|
||||
'''
|
||||
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class ZiuaVeche(BasicNewsRecipe):
|
||||
title = u'Ziua Veche'
|
||||
__author__ = u'Silviu Cotoar\u0103'
|
||||
description = 'Cotidian online'
|
||||
publisher = 'Ziua Veche'
|
||||
oldest_article = 5
|
||||
language = 'ro'
|
||||
max_articles_per_feed = 100
|
||||
no_stylesheets = True
|
||||
use_embedded_content = False
|
||||
category = 'Ziare,Cotidiane,Stiri'
|
||||
encoding = 'utf-8'
|
||||
cover_url = 'http://www.ziuaveche.ro/wp-content/themes/tema/images/zv-logo-alb-old.png'
|
||||
|
||||
conversion_options = {
|
||||
'comments' : description
|
||||
,'tags' : category
|
||||
,'language' : language
|
||||
,'publisher' : publisher
|
||||
}
|
||||
|
||||
|
||||
keep_only_tags = [
|
||||
dict(name='div', attrs={'id':'singlePost'})
|
||||
|
||||
]
|
||||
|
||||
remove_tags = [
|
||||
dict(name='div', attrs={'id':'LikePluginPagelet'})
|
||||
|
||||
]
|
||||
|
||||
remove_tags_after = [
|
||||
dict(name='div', attrs={'id':'LikePluginPagelet'})
|
||||
]
|
||||
|
||||
feeds = [
|
||||
(u'Feeds', u'http://www.ziuaveche.ro/feed/rss')
|
||||
]
|
||||
|
||||
def preprocess_html(self, soup):
|
||||
return self.adeify_images(soup)
|
@ -203,9 +203,11 @@ class ITUNES(DriverBase):
|
||||
# 0x1294 iPhone 3GS
|
||||
# 0x1297 iPhone 4
|
||||
# 0x129a iPad
|
||||
# 0x12a2 iPad2
|
||||
# 0x129f iPad2 (WiFi)
|
||||
# 0x12a2 iPad2 (GSM)
|
||||
# 0x12a3 iPad2 (CDMA)
|
||||
VENDOR_ID = [0x05ac]
|
||||
PRODUCT_ID = [0x1292,0x1293,0x1294,0x1297,0x1299,0x129a,0x12a2]
|
||||
PRODUCT_ID = [0x1292,0x1293,0x1294,0x1297,0x1299,0x129a,0x129f,0x12a2,0x12a3]
|
||||
BCD = [0x01]
|
||||
|
||||
# Plugboard ID
|
||||
|
@ -68,7 +68,8 @@ def check_command_line_options(parser, args, log):
|
||||
raise SystemExit(1)
|
||||
|
||||
output = args[2]
|
||||
if output.startswith('.') and output != '.':
|
||||
if output.startswith('.') and (output != '.' and not
|
||||
output.startswith('..')):
|
||||
output = os.path.splitext(os.path.basename(input))[0]+output
|
||||
output = os.path.abspath(output)
|
||||
|
||||
|
@ -7,7 +7,6 @@ __copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import os
|
||||
import posixpath
|
||||
|
||||
from calibre import guess_type, walk
|
||||
from calibre.customize.conversion import InputFormatPlugin
|
||||
@ -74,22 +73,23 @@ class HTMLZInput(InputFormatPlugin):
|
||||
meta_info_to_oeb_metadata(mi, oeb.metadata, log)
|
||||
|
||||
# Get the cover path from the OPF.
|
||||
cover_href = None
|
||||
cover_path = None
|
||||
opf = None
|
||||
for x in walk('.'):
|
||||
if os.path.splitext(x)[1].lower() in ('.opf'):
|
||||
opf = x
|
||||
break
|
||||
if opf:
|
||||
opf = OPF(opf)
|
||||
cover_href = posixpath.relpath(opf.cover, os.path.dirname(stream.name))
|
||||
opf = OPF(opf, basedir=os.getcwd())
|
||||
cover_path = opf.raster_cover
|
||||
# Set the cover.
|
||||
if cover_href:
|
||||
if cover_path:
|
||||
cdata = None
|
||||
with open(cover_href, 'rb') as cf:
|
||||
with open(os.path.join(os.getcwd(), cover_path), 'rb') as cf:
|
||||
cdata = cf.read()
|
||||
id, href = oeb.manifest.generate('cover', cover_href)
|
||||
oeb.manifest.add(id, href, guess_type(cover_href)[0], data=cdata)
|
||||
cover_name = os.path.basename(cover_path)
|
||||
id, href = oeb.manifest.generate('cover', cover_name)
|
||||
oeb.manifest.add(id, href, guess_type(cover_name)[0], data=cdata)
|
||||
oeb.guide.add('cover', 'Cover', href)
|
||||
|
||||
return oeb
|
||||
|
@ -8,12 +8,11 @@ Read meta information from extZ (TXTZ, HTMLZ...) files.
|
||||
'''
|
||||
|
||||
import os
|
||||
import posixpath
|
||||
|
||||
from cStringIO import StringIO
|
||||
|
||||
from calibre.ebooks.metadata import MetaInformation
|
||||
from calibre.ebooks.metadata.opf2 import OPF, metadata_to_opf
|
||||
from calibre.ebooks.metadata.opf2 import OPF
|
||||
from calibre.ptempfile import PersistentTemporaryFile
|
||||
from calibre.utils.zipfile import ZipFile, safe_replace
|
||||
|
||||
@ -31,9 +30,9 @@ def get_metadata(stream, extract_cover=True):
|
||||
opf = OPF(opf_stream)
|
||||
mi = opf.to_book_metadata()
|
||||
if extract_cover:
|
||||
cover_href = posixpath.relpath(opf.cover, os.path.dirname(stream.name))
|
||||
cover_href = opf.raster_cover
|
||||
if cover_href:
|
||||
mi.cover_data = ('jpg', zf.read(cover_href))
|
||||
mi.cover_data = (os.path.splitext(cover_href)[1], zf.read(cover_href))
|
||||
except:
|
||||
return mi
|
||||
return mi
|
||||
@ -59,18 +58,15 @@ def set_metadata(stream, mi):
|
||||
except:
|
||||
pass
|
||||
if new_cdata:
|
||||
cover = opf.cover
|
||||
if not cover:
|
||||
cover = 'cover.jpg'
|
||||
cpath = posixpath.join(posixpath.dirname(opf_path), cover)
|
||||
cpath = opf.raster_cover
|
||||
if not cpath:
|
||||
cpath = 'cover.jpg'
|
||||
new_cover = _write_new_cover(new_cdata, cpath)
|
||||
replacements[cpath] = open(new_cover.name, 'rb')
|
||||
mi.cover = cover
|
||||
mi.cover = cpath
|
||||
|
||||
# Update the metadata.
|
||||
old_mi = opf.to_book_metadata()
|
||||
old_mi.smart_update(mi)
|
||||
opf.smart_update(metadata_to_opf(old_mi), replace_metadata=True)
|
||||
opf.smart_update(mi, replace_metadata=True)
|
||||
newopf = StringIO(opf.render())
|
||||
safe_replace(stream, opf_path, newopf, extra_replacements=replacements, add_missing=True)
|
||||
|
||||
|
@ -338,7 +338,7 @@ class Amazon(Source):
|
||||
q['field-author'] = ' '.join(author_tokens)
|
||||
|
||||
if not ('field-keywords' in q or 'field-isbn' in q or
|
||||
('field-title' in q and 'field-author' in q)):
|
||||
('field-title' in q)):
|
||||
# Insufficient metadata to make an identify query
|
||||
return None
|
||||
|
||||
|
@ -212,6 +212,9 @@ class Source(Plugin):
|
||||
def is_customizable(self):
|
||||
return True
|
||||
|
||||
def customization_help(self):
|
||||
return 'This plugin can only be customized using the GUI'
|
||||
|
||||
def config_widget(self):
|
||||
from calibre.gui2.metadata.config import ConfigWidget
|
||||
return ConfigWidget(self)
|
||||
@ -288,10 +291,10 @@ class Source(Plugin):
|
||||
parts = parts[1:] + parts[:1]
|
||||
for tok in parts:
|
||||
tok = remove_pat.sub('', tok).strip()
|
||||
if len(tok) > 2 and tok.lower() not in ('von', ):
|
||||
if len(tok) > 2 and tok.lower() not in ('von', 'van',
|
||||
_('Unknown').lower()):
|
||||
yield tok
|
||||
|
||||
|
||||
def get_title_tokens(self, title, strip_joiners=True, strip_subtitle=False):
|
||||
'''
|
||||
Take a title and return a list of tokens useful for an AND search query.
|
||||
|
@ -20,6 +20,9 @@ class GenerateCatalogAction(InterfaceAction):
|
||||
action_spec = (_('Create a catalog of the books in your calibre library'), 'catalog.png', 'Catalog builder', None)
|
||||
dont_add_to = frozenset(['menubar-device', 'toolbar-device', 'context-menu-device'])
|
||||
|
||||
def genesis(self):
|
||||
self.qaction.triggered.connect(self.generate_catalog)
|
||||
|
||||
def generate_catalog(self):
|
||||
rows = self.gui.library_view.selectionModel().selectedRows()
|
||||
if not rows or len(rows) < 2:
|
||||
|
@ -19,9 +19,13 @@ class MessageBox(QDialog, Ui_Dialog): # {{{
|
||||
INFO = 2
|
||||
QUESTION = 3
|
||||
|
||||
def __init__(self, type_, title, msg, det_msg='', show_copy_button=True,
|
||||
def __init__(self, type_, title, msg,
|
||||
det_msg='',
|
||||
q_icon=None,
|
||||
show_copy_button=True,
|
||||
parent=None):
|
||||
QDialog.__init__(self, parent)
|
||||
if q_icon is None:
|
||||
icon = {
|
||||
self.ERROR : 'error',
|
||||
self.WARNING: 'warning',
|
||||
@ -30,6 +34,8 @@ class MessageBox(QDialog, Ui_Dialog): # {{{
|
||||
}[type_]
|
||||
icon = 'dialog_%s.png'%icon
|
||||
self.icon = QIcon(I(icon))
|
||||
else:
|
||||
self.icon = q_icon
|
||||
self.setupUi(self)
|
||||
|
||||
self.setWindowTitle(title)
|
||||
@ -44,7 +50,6 @@ class MessageBox(QDialog, Ui_Dialog): # {{{
|
||||
self.bb.ActionRole)
|
||||
self.ctc_button.clicked.connect(self.copy_to_clipboard)
|
||||
|
||||
|
||||
self.show_det_msg = _('Show &details')
|
||||
self.hide_det_msg = _('Hide &details')
|
||||
self.det_msg_toggle = self.bb.addButton(self.show_det_msg, self.bb.ActionRole)
|
||||
|
@ -1126,7 +1126,7 @@ class DateEdit(QDateEdit): # {{{
|
||||
@dynamic_property
|
||||
def current_val(self):
|
||||
def fget(self):
|
||||
return qt_to_dt(self.date())
|
||||
return qt_to_dt(self.date(), as_utc=False)
|
||||
def fset(self, val):
|
||||
if val is None:
|
||||
val = UNDEFINED_DATE
|
||||
|
@ -31,6 +31,7 @@ class MetadataSingleDialogBase(ResizableDialog):
|
||||
view_format = pyqtSignal(object, object)
|
||||
cc_two_column = tweaks['metadata_single_use_2_cols_for_custom_fields']
|
||||
one_line_comments_toolbar = False
|
||||
use_toolbutton_for_config_metadata = True
|
||||
|
||||
def __init__(self, db, parent=None):
|
||||
self.db = db
|
||||
@ -71,7 +72,9 @@ class MetadataSingleDialogBase(ResizableDialog):
|
||||
self.l.addWidget(self.scroll_area)
|
||||
ll = self.button_box_layout = QHBoxLayout()
|
||||
self.l.addLayout(ll)
|
||||
ll.addSpacing(10)
|
||||
ll.addWidget(self.button_box)
|
||||
ll.addSpacing(10)
|
||||
|
||||
self.setWindowIcon(QIcon(I('edit_input.png')))
|
||||
self.setWindowTitle(_('Edit Metadata'))
|
||||
@ -191,8 +194,13 @@ class MetadataSingleDialogBase(ResizableDialog):
|
||||
font.setBold(True)
|
||||
self.fetch_metadata_button.setFont(font)
|
||||
|
||||
if self.use_toolbutton_for_config_metadata:
|
||||
self.config_metadata_button = QToolButton(self)
|
||||
self.config_metadata_button.setIcon(QIcon(I('config.png')))
|
||||
else:
|
||||
self.config_metadata_button = QPushButton(self)
|
||||
self.config_metadata_button.setText(_('Configure download metadata'))
|
||||
self.config_metadata_button.setIcon(QIcon(I('config.png')))
|
||||
self.config_metadata_button.clicked.connect(self.configure_metadata)
|
||||
self.config_metadata_button.setToolTip(
|
||||
_('Change how calibre downloads metadata'))
|
||||
@ -614,6 +622,7 @@ class MetadataSingleDialogAlt1(MetadataSingleDialogBase): # {{{
|
||||
|
||||
cc_two_column = False
|
||||
one_line_comments_toolbar = True
|
||||
use_toolbutton_for_config_metadata = False
|
||||
|
||||
on_drag_enter = pyqtSignal()
|
||||
|
||||
@ -649,10 +658,8 @@ class MetadataSingleDialogAlt1(MetadataSingleDialogBase): # {{{
|
||||
self.tabs[0].l.addWidget(gb, 0, 0, 1, 1)
|
||||
gb.setLayout(tl)
|
||||
|
||||
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_layout.insertWidget(1, self.config_metadata_button)
|
||||
self.button_box_layout.insertWidget(1, self.fetch_metadata_button)
|
||||
self.button_box_layout.insertWidget(2, 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)
|
||||
@ -767,6 +774,7 @@ class MetadataSingleDialogAlt2(MetadataSingleDialogBase): # {{{
|
||||
|
||||
cc_two_column = False
|
||||
one_line_comments_toolbar = True
|
||||
use_toolbutton_for_config_metadata = False
|
||||
|
||||
def do_layout(self):
|
||||
self.central_widget.clear()
|
||||
@ -785,10 +793,8 @@ class MetadataSingleDialogAlt2(MetadataSingleDialogBase): # {{{
|
||||
l.addWidget(gb, 0, 0, 1, 1)
|
||||
gb.setLayout(tl)
|
||||
|
||||
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_layout.insertWidget(1, self.config_metadata_button)
|
||||
self.button_box_layout.insertWidget(1, self.fetch_metadata_button)
|
||||
self.button_box_layout.insertWidget(2, 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)
|
||||
|
@ -10,6 +10,7 @@ License: http://www.opensource.org/licenses/mit-license.php
|
||||
import re
|
||||
|
||||
from calibre.utils.icu import capitalize
|
||||
from calibre.utils.config import prefs
|
||||
|
||||
__all__ = ['titlecase']
|
||||
__version__ = '0.5'
|
||||
@ -67,6 +68,7 @@ def titlecase(text):
|
||||
line.append(icu_lower(word))
|
||||
continue
|
||||
|
||||
if prefs['language'].lower().startswith('en'):
|
||||
match = MAC_MC.match(word)
|
||||
if match and not match.group(2)[:3] in ('hin', 'ht'):
|
||||
line.append("%s%s" % (capitalize(match.group(1)),
|
||||
|
Loading…
x
Reference in New Issue
Block a user