mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
Sync to trunk.
This commit is contained in:
commit
fe64ffb3a5
134
Changelog.yaml
134
Changelog.yaml
@ -4,6 +4,140 @@
|
||||
# for important features/bug fixes.
|
||||
# Also, each release can have new and improved recipes.
|
||||
|
||||
- version: 0.6.35
|
||||
date: 2010-01-22
|
||||
|
||||
new features:
|
||||
- title: Catalog generation
|
||||
type: major
|
||||
description: >
|
||||
"You can now easily generate a catlog of all books in your calibre library by clicking the arrow next to the convert button. The catalog can be in one of several formats: XML, CSV, EPUB and MOBI, with scope for future formats via plugins. If you generate the catalog in an e-book format, it will be automatically sent to your e-book reader the next time you connect it, allowing you to easily browse your collection on the reader itself. This feature is in Beta (may have bugs) so feedback is appreciated."
|
||||
|
||||
- title: "RTF Input: Support for unicode characters."
|
||||
type: major
|
||||
tickets: [4501]
|
||||
|
||||
- title: "Add Quick Start Guide by John Schember to calibre library on first run of calibre"
|
||||
type: major
|
||||
|
||||
- title: "Improve handling of justification"
|
||||
description: >
|
||||
"Now calibre will explicitly change the justification of all left aligned paragraphs to justified or vice versa depending on the justification setting. This should make it possible to robustly convert all content to either justified or not. calibre will not touch centered or right aligned content."
|
||||
|
||||
- title: "E-book viewer: Fit images to viewer window (can be turned off via Preferences)"
|
||||
|
||||
- title: "Add section on E-book viewer to User Manual"
|
||||
|
||||
- title: "Development environment: First look for resources in the location pointed to by CALIBRE_DEVELOP_FROM. If not found, use the normal resource location"
|
||||
|
||||
- title: "When reading metadata from filenames, with the Swap author names option checked, improve the logic used to detect author last name."
|
||||
tickets: [4620]
|
||||
|
||||
- title: "News downloads: When getting an article URL from a RSS feed, look first for an original article link. This speeds up the download of news services that use a syndication service like feedburner or pheedo to publish their RSS feeds."
|
||||
|
||||
bug fixes:
|
||||
- "Windows device detection: Don't do expensive polling while waiting for device disconnect. This should fix the problems people have with their floppy drive being activated while an e-book reader is connected"
|
||||
|
||||
- title: "PML Input: Fix creation of metadata Table of Contents"
|
||||
tickets: [5633]
|
||||
|
||||
- title: "Fix Tag browser not updating after using delete specific format actions"
|
||||
tickets: [4632]
|
||||
|
||||
- title: "MOBI Output: Don't die when converting EPUB files with SVG covers"
|
||||
|
||||
- title: "Nook driver: Remove the # character from filenames when sending to device"
|
||||
tickets: [4629]
|
||||
|
||||
- title: "Workaround for bug in QtWebKit on windows that could cause crashes when using the next page button in the e-book viewer for certain files"
|
||||
tickets: [4606]
|
||||
|
||||
- title: "MOBI Input: Rescale img width and height attributes that were specified in em units"
|
||||
tickets: [4608]
|
||||
|
||||
- title: "ebook-meta: Fix setting of series metadata"
|
||||
|
||||
- title: "RTF metadata: Fix reading metadata from very small files"
|
||||
|
||||
- title: "Conversion pipeline: Don't error out if the user sets an invalid chapter detection XPath"
|
||||
|
||||
- title: "Fix main mem and card being swapped in pocketbook detection on OS X"
|
||||
|
||||
- title: "Welcome wizard: Set the language to english if the user doesn't explicitly change the language. This ensures that the language will be english on windows by default"
|
||||
|
||||
- title: "Fix bug in OEBWriter that could cause writing out of resources in subdirectories with URL unsafe names to fail"
|
||||
|
||||
- title: "E-book viewer: Change highlight color to yellow on all platforms."
|
||||
tickets: [4641]
|
||||
|
||||
new recipes:
|
||||
- title: Frankfurter Rundschau
|
||||
author: Justus Bisser
|
||||
|
||||
- title: The Columbia Hournalism Review
|
||||
author: XanthanGum
|
||||
|
||||
- title: Various CanWest Canadian news sources
|
||||
author: Nick Redding
|
||||
|
||||
- title: gigitaljournal.com
|
||||
author: Darko Miletic
|
||||
|
||||
- title: Pajamas Media
|
||||
autor: Krittika Goyal
|
||||
|
||||
- title: Algemeen Dagbla
|
||||
author: kwetal
|
||||
|
||||
- title: "The Reader's Digest"
|
||||
author: BrianG
|
||||
|
||||
- title: The Yemen Times
|
||||
author: kwetal
|
||||
|
||||
- title: The Kitsap Sun
|
||||
author: Darko Miletic
|
||||
|
||||
- title: drivelry.com
|
||||
author: Krittika Goyal
|
||||
|
||||
- title: New recipe for Google Reader that downloads unread articles instead of just starred ones
|
||||
author: rollercoaster
|
||||
|
||||
- title: Le Devoir
|
||||
author: Lorenzo Vigentini
|
||||
|
||||
- title: Joop
|
||||
author: kwetal
|
||||
|
||||
- title: Various computer magazines
|
||||
author: Lorenzo Vigentini
|
||||
|
||||
- title: The Wall Street journal (free parts)
|
||||
author: Nick Redding
|
||||
|
||||
- title: Journal of Nephrology
|
||||
author: Krittika Goyal
|
||||
|
||||
- title: stuff.co.nz
|
||||
author: Krittika Goyal
|
||||
|
||||
- title: Editor and Publisher
|
||||
author: XanthanGum
|
||||
|
||||
- title: The Week (free)
|
||||
author: Darko Miletic
|
||||
|
||||
improved recipes:
|
||||
- Physics Today
|
||||
- Wall Street Journal
|
||||
- American Spectator
|
||||
- FTD
|
||||
- The National Post
|
||||
- Blic
|
||||
- Ars Technica
|
||||
|
||||
|
||||
- version: 0.6.34
|
||||
date: 2010-01-15
|
||||
|
||||
|
BIN
resources/catalog/DefaultCover.jpg
Normal file
BIN
resources/catalog/DefaultCover.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
BIN
resources/catalog/mastheadImage.gif
Normal file
BIN
resources/catalog/mastheadImage.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
62
resources/catalog/stylesheet.css
Normal file
62
resources/catalog/stylesheet.css
Normal file
@ -0,0 +1,62 @@
|
||||
p.title {
|
||||
margin-top:0em;
|
||||
margin-bottom:1em;
|
||||
text-align:center;
|
||||
font-style:italic;
|
||||
font-size:xx-large;
|
||||
border-bottom: solid black 4px;
|
||||
}
|
||||
|
||||
p.author {
|
||||
margin-top:0em;
|
||||
margin-bottom:0em;
|
||||
text-align: left;
|
||||
text-indent: 1em;
|
||||
font-size:large;
|
||||
}
|
||||
|
||||
p.tags {
|
||||
margin-top:0em;
|
||||
margin-bottom:0em;
|
||||
text-align: left;
|
||||
text-indent: 1em;
|
||||
font-size:small;
|
||||
}
|
||||
|
||||
p.description {
|
||||
text-align:left;
|
||||
font-style:italic;
|
||||
margin-top: 0em;
|
||||
}
|
||||
|
||||
p.letter_index {
|
||||
font-size:x-large;
|
||||
text-align:left;
|
||||
margin-top:0px;
|
||||
margin-bottom:0px;
|
||||
}
|
||||
|
||||
p.author_index {
|
||||
font-size:large;
|
||||
text-align:left;
|
||||
margin-top:0px;
|
||||
margin-bottom:0px;
|
||||
text-indent: 0em;
|
||||
}
|
||||
|
||||
p.read_book {
|
||||
text-align:left;
|
||||
margin-top:0px;
|
||||
margin-bottom:0px;
|
||||
margin-left:2em;
|
||||
text-indent:-2em;
|
||||
}
|
||||
|
||||
p.unread_book {
|
||||
text-align:left;
|
||||
margin-top:0px;
|
||||
margin-bottom:0px;
|
||||
margin-left:2em;
|
||||
text-indent:-2em;
|
||||
}
|
||||
|
BIN
resources/images/news/the_week_magazine_free.png
Normal file
BIN
resources/images/news/the_week_magazine_free.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 301 B |
@ -1,12 +1,12 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
|
||||
__copyright__ = '2008-2010, Darko Miletic <darko.miletic at gmail.com>'
|
||||
'''
|
||||
arstechnica.com
|
||||
'''
|
||||
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
from calibre.ebooks.BeautifulSoup import BeautifulSoup, Tag
|
||||
|
||||
class ArsTechnica2(BasicNewsRecipe):
|
||||
title = u'Ars Technica'
|
||||
@ -18,24 +18,24 @@ class ArsTechnica2(BasicNewsRecipe):
|
||||
oldest_article = 2
|
||||
max_articles_per_feed = 100
|
||||
no_stylesheets = True
|
||||
encoding = 'utf8'
|
||||
remove_javascript = True
|
||||
encoding = 'utf-8'
|
||||
use_embedded_content = False
|
||||
extra_css = ' body {font-family: sans-serif} .byline{font-weight: bold; line-height: 1em; font-size: 0.625em; text-decoration: none} '
|
||||
|
||||
extra_css = '''
|
||||
.news-item-title{font-size: medium ;font-family:Arial,Helvetica,sans-serif; font-weight:bold;}
|
||||
.news-item-teaser{font-size: small ;font-family:Arial,Helvetica,sans-serif; font-weight:bold;}
|
||||
.news-item-byline{font-size:xx-small; font-family:Arial,Helvetica,sans-serif;font-weight:normal;}
|
||||
.news-item-text{font-size:x-small;font-family:Arial,Helvetica,sans-serif;}
|
||||
.news-item-figure-caption-text{font-size:xx-small; font-family:Arial,Helvetica,sans-serif;font-weight:bold;}
|
||||
.news-item-figure-caption-byline{font-size:xx-small; font-family:Arial,Helvetica,sans-serif;font-weight:normal;}
|
||||
'''
|
||||
conversion_options = {
|
||||
'comments' : description
|
||||
,'tags' : category
|
||||
,'language' : language
|
||||
,'publisher' : publisher
|
||||
}
|
||||
|
||||
keep_only_tags = [dict(name='div', attrs={'id':['news-item-info','news-item']})]
|
||||
|
||||
|
||||
keep_only_tags = [dict(name='div', attrs={'id':['story','etc-story']})]
|
||||
|
||||
remove_tags = [
|
||||
dict(name=['object','link','embed'])
|
||||
,dict(name='div', attrs={'class':'related-stories'})
|
||||
,dict(name='div', attrs={'class':'read-more-link'})
|
||||
]
|
||||
|
||||
|
||||
@ -52,14 +52,19 @@ class ArsTechnica2(BasicNewsRecipe):
|
||||
]
|
||||
|
||||
def append_page(self, soup, appendtag, position):
|
||||
pager = soup.find('div',attrs={'id':'pager'})
|
||||
pager = soup.find('div',attrs={'class':'pager'})
|
||||
if pager:
|
||||
for atag in pager.findAll('a',href=True):
|
||||
str = self.tag_to_string(atag)
|
||||
if str.startswith('Next'):
|
||||
soup2 = self.index_to_soup(atag['href'])
|
||||
|
||||
texttag = soup2.find('div', attrs={'class':'news-item-text'})
|
||||
nurl = 'http://arstechnica.com' + atag['href']
|
||||
rawc = self.index_to_soup(nurl,True)
|
||||
soup2 = BeautifulSoup(rawc, fromEncoding=self.encoding)
|
||||
|
||||
readmoretag = soup2.find('div', attrs={'class':'read-more-link'})
|
||||
if readmoretag:
|
||||
readmoretag.extract()
|
||||
texttag = soup2.find('div', attrs={'class':'body'})
|
||||
for it in texttag.findAll(style=True):
|
||||
del it['style']
|
||||
|
||||
@ -71,10 +76,12 @@ class ArsTechnica2(BasicNewsRecipe):
|
||||
|
||||
|
||||
def preprocess_html(self, soup):
|
||||
|
||||
ftag = soup.find('div', attrs={'class':'news-item-byline'})
|
||||
ftag = soup.find('div', attrs={'class':'byline'})
|
||||
if ftag:
|
||||
ftag.insert(4,'<br /><br />')
|
||||
brtag = Tag(soup,'br')
|
||||
brtag2 = Tag(soup,'br')
|
||||
ftag.insert(4,brtag)
|
||||
ftag.insert(5,brtag2)
|
||||
|
||||
for item in soup.findAll(style=True):
|
||||
del item['style']
|
||||
@ -83,5 +90,7 @@ class ArsTechnica2(BasicNewsRecipe):
|
||||
|
||||
return soup
|
||||
|
||||
def get_article_url(self, article):
|
||||
return article.get('feedburner_origlink', None).rpartition('?')[0]
|
||||
|
||||
|
||||
|
34
resources/recipes/editor_and_publisher.recipe
Normal file
34
resources/recipes/editor_and_publisher.recipe
Normal file
@ -0,0 +1,34 @@
|
||||
import re
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
class EandP(BasicNewsRecipe):
|
||||
title = u'Editor and Publisher'
|
||||
__author__ = u'Xanthan Gum'
|
||||
description = 'News about newspapers and journalism.'
|
||||
language = 'en'
|
||||
no_stylesheets = True
|
||||
|
||||
oldest_article = 7
|
||||
max_articles_per_feed = 100
|
||||
|
||||
# Font formatting code borrowed from kwetal
|
||||
|
||||
extra_css = '''
|
||||
body{font-family:verdana,arial,helvetica,geneva,sans-serif ;}
|
||||
h1{font-size: xx-large;}
|
||||
h2{font-size: large;}
|
||||
'''
|
||||
|
||||
# Delete everything before the article
|
||||
|
||||
remove_tags_before = dict(name='font', attrs={'class':'titlebar_black'})
|
||||
|
||||
# Delete everything after the article
|
||||
|
||||
preprocess_regexps = [(re.compile(r'<!--endclickprintinclude-->.*</body>', re.DOTALL|re.IGNORECASE),
|
||||
lambda match: '</body>'),]
|
||||
|
||||
feeds = [(u'Breaking News', u'http://feeds.feedburner.com/EditorAndPublisher-BreakingNews'),
|
||||
(u'Business News', u'http://feeds.feedburner.com/EditorAndPublisher-BusinessNews'),
|
||||
(u'Newsroom', u'http://feeds.feedburner.com/EditorAndPublisher-Newsroom'),
|
||||
(u'Technology News', u'http://feeds.feedburner.com/EditorAndPublisher-Technology'),
|
||||
(u'Syndicates News', u'http://feeds.feedburner.com/EditorAndPublisher-Syndicates')]
|
67
resources/recipes/fr_online.recipe
Normal file
67
resources/recipes/fr_online.recipe
Normal file
@ -0,0 +1,67 @@
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2009, Justus Bisser <justus.bisser at gmail.com>'
|
||||
'''
|
||||
fr-online.de
|
||||
'''
|
||||
import re
|
||||
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class Spiegel_ger(BasicNewsRecipe):
|
||||
title = 'Frankfurter Rundschau'
|
||||
__author__ = 'Justus Bisser'
|
||||
description = "Dies ist die Online-Ausgabe der Frankfurter Rundschau. Um die abgerufenen individuell einzustellen bearbeiten sie die Liste im erweiterten Modus. Die Feeds findet man auf http://www.fr-online.de/verlagsservice/fr_newsreader/?em_cnt=574255"
|
||||
publisher = 'Druck- und Verlagshaus Frankfurt am Main GmbH'
|
||||
category = 'FR Online, Frankfurter Rundschau, Nachrichten, News,Dienste, RSS, RSS, Feedreader, Newsfeed, iGoogle, Netvibes, Widget'
|
||||
oldest_article = 7
|
||||
max_articles_per_feed = 100
|
||||
language = 'de'
|
||||
lang = 'de-DE'
|
||||
no_stylesheets = True
|
||||
use_embedded_content = False
|
||||
#encoding = 'cp1252'
|
||||
|
||||
conversion_options = {
|
||||
'comment' : description
|
||||
, 'tags' : category
|
||||
, 'publisher' : publisher
|
||||
, 'language' : lang
|
||||
}
|
||||
|
||||
recursions = 0
|
||||
max_articles_per_feed = 100
|
||||
#keep_only_tags = [dict(name='div', attrs={'class':'text'})]
|
||||
#tags_remove = [dict(name='div', attrs={'style':'text-align: left; margin: 4px 0px 0px 4px; width: 200px; float: right;'})]
|
||||
remove_attributes = ['style']
|
||||
feeds = []
|
||||
#remove_tags_before = [dict(name='div', attrs={'style':'padding-left: 0px;'})]
|
||||
#remove_tags_after = [dict(name='div', attrs={'class':'box_head_text'})]
|
||||
|
||||
# enable for all news
|
||||
allNews = 0
|
||||
if allNews:
|
||||
feeds = [(u'Frankfurter Rundschau', u'http://www.fr-online.de/rss/sport/index.xml')]
|
||||
else:
|
||||
#select the feeds you like
|
||||
feeds = [(u'Nachrichten', u'http://www.fr-online.de/rss/politik/index.xml')]
|
||||
feeds.append((u'Kommentare und Analysen', u'http://www.fr-online.de/rss/meinung/index.xml'))
|
||||
feeds.append((u'Dokumentationen', u'http://www.fr-online.de/rss/dokumentation/index.xml'))
|
||||
feeds.append((u'Deutschlandtrend', u'http://www.fr-online.de/rss/deutschlandtrend/index.xml'))
|
||||
feeds.append((u'Wirtschaft', u'http://www.fr-online.de/rss/wirtschaft/index.xml'))
|
||||
feeds.append((u'Sport', u'http://www.fr-online.de/rss/sport/index.xml'))
|
||||
feeds.append((u'Feuilleton', u'http://www.fr-online.de/rss/feuilleton/index.xml'))
|
||||
feeds.append((u'Panorama', u'http://www.fr-online.de/rss/panorama/index.xml'))
|
||||
feeds.append((u'Rhein Main und Hessen', u'http://www.fr-online.de/rss/hessen/index.xml'))
|
||||
feeds.append((u'Fitness und Gesundheit', u'http://www.fr-online.de/rss/fit/index.xml'))
|
||||
feeds.append((u'Multimedia', u'http://www.fr-online.de/rss/multimedia/index.xml'))
|
||||
feeds.append((u'Wissen und Bildung', u'http://www.fr-online.de/rss/wissen/index.xml'))
|
||||
|
||||
def get_article_url(self, article):
|
||||
url = article.link
|
||||
regex = re.compile("0C[0-9]{6,8}0A?")
|
||||
|
||||
liste = regex.findall(url)
|
||||
string = liste.pop(0)
|
||||
string = string[2:len(string)-1]
|
||||
return "http://www.fr-online.de/_em_cms/_globals/print.php?em_cnt=" + string
|
||||
|
@ -9,16 +9,16 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
|
||||
class FTDe(BasicNewsRecipe):
|
||||
|
||||
|
||||
title = 'FTD'
|
||||
description = 'Financial Times Deutschland'
|
||||
__author__ = 'Oliver Niesner'
|
||||
use_embedded_content = False
|
||||
timefmt = ' [%d %b %Y]'
|
||||
language = _('German')
|
||||
language = 'de'
|
||||
max_articles_per_feed = 40
|
||||
no_stylesheets = True
|
||||
|
||||
|
||||
remove_tags = [dict(id='navi_top'),
|
||||
dict(id='topbanner'),
|
||||
dict(id='seitenkopf'),
|
||||
@ -83,8 +83,8 @@ class FTDe(BasicNewsRecipe):
|
||||
dict(name='div', attrs={'class':'articleOptionFootFrame'}),
|
||||
dict(name='div', attrs={'class':'artikelsplitfaq'})]
|
||||
#remove_tags_after = [dict(name='a', attrs={'class':'more'})]
|
||||
|
||||
feeds = [ ('Finanzen', 'http://www.ftd.de/rss2/finanzen/maerkte'),
|
||||
|
||||
feeds = [ ('Finanzen', 'http://www.ftd.de/rss2/finanzen/maerkte'),
|
||||
('Meinungshungrige', 'http://www.ftd.de/rss2/meinungshungrige'),
|
||||
('Unternehmen', 'http://www.ftd.de/rss2/unternehmen'),
|
||||
('Politik', 'http://www.ftd.de/rss2/politik'),
|
||||
@ -95,8 +95,8 @@ class FTDe(BasicNewsRecipe):
|
||||
('Auto', 'http://www.ftd.de/rss2/auto'),
|
||||
('Lifestyle', 'http://www.ftd.de/rss2/lifestyle')
|
||||
|
||||
]
|
||||
|
||||
]
|
||||
|
||||
|
||||
def print_version(self, url):
|
||||
return url.replace('.html', '.html?mode=print')
|
||||
|
49
resources/recipes/the_week_magazine_free.recipe
Normal file
49
resources/recipes/the_week_magazine_free.recipe
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2010, Darko Miletic <darko.miletic at gmail.com>'
|
||||
'''
|
||||
www.theweek.com
|
||||
'''
|
||||
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class TheWeekFree(BasicNewsRecipe):
|
||||
title = 'The Week Magazine - Free content'
|
||||
__author__ = 'Darko Miletic'
|
||||
description = "The best of the US and international media. Daily coverage of commentary and analysis of the day's events, as well as arts, entertainment, people and gossip, and political cartoons."
|
||||
publisher = 'The Week Publications, Inc.'
|
||||
category = 'news, politics, USA'
|
||||
oldest_article = 7
|
||||
max_articles_per_feed = 100
|
||||
no_stylesheets = True
|
||||
encoding = 'utf-8'
|
||||
use_embedded_content = False
|
||||
language = 'en'
|
||||
|
||||
conversion_options = {
|
||||
'comment' : description
|
||||
, 'tags' : category
|
||||
, 'publisher' : publisher
|
||||
, 'language' : language
|
||||
}
|
||||
|
||||
keep_only_tags = [
|
||||
dict(name=['h1','h2'])
|
||||
, dict(name='div', attrs={'class':'basefont'})
|
||||
, dict(name='div', attrs={'id':'slideshowLoader'})
|
||||
]
|
||||
|
||||
remove_tags = [
|
||||
dict(name='div', attrs={'id':['digg_dugg','articleRight','dateHeader']})
|
||||
,dict(name=['object','embed','iframe'])
|
||||
]
|
||||
|
||||
|
||||
feeds = [
|
||||
(u'News & Opinions' , u'http://www.theweek.com/section/index/news_opinion.rss')
|
||||
,(u'Arts & Leisure' , u'http://www.theweek.com/section/index/arts_leisure.rss')
|
||||
,(u'Business' , u'http://www.theweek.com/section/index/business.rss' )
|
||||
,(u'Cartoon & Short takes' , u'http://www.theweek.com/section/index/cartoons_wit.rss')
|
||||
]
|
||||
|
||||
|
@ -312,7 +312,7 @@ class CatalogPlugin(Plugin):
|
||||
continue
|
||||
resources.close()
|
||||
|
||||
def run(self, path_to_output, opts, db, ids):
|
||||
def run(self, path_to_output, opts, db, ids, notification=None):
|
||||
'''
|
||||
Run the plugin. Must be implemented in subclasses.
|
||||
It should generate the catalog in the format specified
|
||||
|
@ -421,8 +421,8 @@ from calibre.devices.binatone.driver import README
|
||||
from calibre.devices.hanvon.driver import N516
|
||||
|
||||
from calibre.ebooks.metadata.fetch import GoogleBooks, ISBNDB, Amazon
|
||||
from calibre.library.catalog import CSV_XML
|
||||
plugins = [HTML2ZIP, PML2PMLZ, GoogleBooks, ISBNDB, Amazon, CSV_XML]
|
||||
from calibre.library.catalog import CSV_XML, EPUB_MOBI
|
||||
plugins = [HTML2ZIP, PML2PMLZ, GoogleBooks, ISBNDB, Amazon, CSV_XML, EPUB_MOBI]
|
||||
plugins += [
|
||||
ComicInput,
|
||||
EPUBInput,
|
||||
|
@ -85,6 +85,9 @@ class OptionRecommendation(object):
|
||||
|
||||
class DummyReporter(object):
|
||||
|
||||
def __init__(self):
|
||||
self.cancel_requested = False
|
||||
|
||||
def __call__(self, percent, msg=''):
|
||||
pass
|
||||
|
||||
|
@ -153,6 +153,21 @@ class Region(object):
|
||||
else:
|
||||
pass
|
||||
|
||||
def contains(self, columns):
|
||||
if not self.columns:
|
||||
return True
|
||||
if len(columns) != len(self.columns):
|
||||
return False
|
||||
for i in range(len(columns)):
|
||||
c1, c2 = self.columns[i], columns[i]
|
||||
x1 = Interval(c1.left, c1.right)
|
||||
x2 = Interval(c2.left, c2.right)
|
||||
intersection = x1.intersection(x2)
|
||||
base = min(x1.width, x2.width)
|
||||
if intersection.width/base < 0.6:
|
||||
return False
|
||||
return True
|
||||
|
||||
class Page(object):
|
||||
|
||||
# Fraction of a character width that two strings have to be apart,
|
||||
|
@ -13,44 +13,34 @@
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<widget class="QListWidget" name="db_fields">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>297</x>
|
||||
<y>20</y>
|
||||
<width>256</width>
|
||||
<height>281</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string extracomment="Select all fields to be exported"/>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::MultiSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>20</y>
|
||||
<width>171</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Fields to include in output:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Fields to include in output:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QListWidget" name="db_fields">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string extracomment="Select all fields to be exported"/>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::MultiSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
54
src/calibre/gui2/catalog/catalog_epub_mobi.py
Normal file
54
src/calibre/gui2/catalog/catalog_epub_mobi.py
Normal file
@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||
from __future__ import with_statement
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
|
||||
from calibre.gui2 import gprefs
|
||||
from catalog_epub_mobi_ui import Ui_Form
|
||||
from calibre.ebooks.conversion.config import load_defaults
|
||||
from PyQt4.Qt import QWidget
|
||||
|
||||
class PluginWidget(QWidget,Ui_Form):
|
||||
|
||||
TITLE = _('EPUB/MOBI Options')
|
||||
HELP = _('Options specific to')+' EPUB/MOBI '+_('output')
|
||||
OPTION_FIELDS = [('exclude_genre','\[[\w ]*\]'),
|
||||
('exclude_tags','~'),
|
||||
('read_tag','+'),
|
||||
('note_tag','*')]
|
||||
|
||||
# Output synced to the connected device?
|
||||
sync_enabled = True
|
||||
|
||||
# Formats supported by this plugin
|
||||
formats = set(['epub','mobi'])
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QWidget.__init__(self, parent)
|
||||
self.setupUi(self)
|
||||
|
||||
def initialize(self, name):
|
||||
self.name = name
|
||||
# Restore options from last use here
|
||||
for opt in self.OPTION_FIELDS:
|
||||
opt_value = gprefs.get(self.name + '_' + opt[0], opt[1])
|
||||
getattr(self, opt[0]).setText(opt_value)
|
||||
|
||||
def options(self):
|
||||
# Save/return the current options
|
||||
opts_dict = {}
|
||||
for opt in self.OPTION_FIELDS:
|
||||
opt_value = unicode(getattr(self, opt[0]).text())
|
||||
gprefs.set(self.name + '_' + opt[0], opt_value)
|
||||
if opt[0] != 'exclude_genre':
|
||||
opt_value = opt_value.split(',')
|
||||
opts_dict[opt[0]] = opt_value
|
||||
|
||||
opts_dict['output_profile'] = [load_defaults('page_setup')['output_profile']]
|
||||
|
||||
|
||||
return opts_dict
|
96
src/calibre/gui2/catalog/catalog_epub_mobi.ui
Normal file
96
src/calibre/gui2/catalog/catalog_epub_mobi.ui
Normal file
@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>579</width>
|
||||
<height>411</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Tags to exclude as genres (regex):</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::LogText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>'Don't include this book' tag:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="exclude_tags">
|
||||
<property name="toolTip">
|
||||
<string extracomment="Tooltip comment here"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>'Mark this book as read' tag:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="read_tag">
|
||||
<property name="toolTip">
|
||||
<string extracomment="Tooltip comment here"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Additional note tag prefix:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="note_tag">
|
||||
<property name="toolTip">
|
||||
<string extracomment="Tooltip comment here"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="exclude_genre">
|
||||
<property name="toolTip">
|
||||
<string extracomment="Tooltip comment here"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -42,21 +42,20 @@ def gui_catalog(fmt, title, dbspec, ids, out_file_name, fmt_options,
|
||||
opts, args = parser.parse_args()
|
||||
|
||||
# Populate opts
|
||||
opts.catalog_title = title
|
||||
opts.ids = ids
|
||||
opts.search_text = None
|
||||
opts.sort_by = None
|
||||
|
||||
# Extract the option dictionary to comma-separated lists
|
||||
for option in fmt_options:
|
||||
setattr(opts,option, ','.join(fmt_options[option]))
|
||||
if isinstance(fmt_options[option],list):
|
||||
setattr(opts,option, ','.join(fmt_options[option]))
|
||||
else:
|
||||
setattr(opts,option, fmt_options[option])
|
||||
|
||||
# Fetch and run the plugin for fmt
|
||||
plugin = plugin_for_catalog_format(fmt)
|
||||
plugin.run(out_file_name, opts, db)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
plugin.run(out_file_name, opts, db, notification=notification)
|
||||
|
||||
|
||||
|
@ -36,9 +36,6 @@ class Catalog(QDialog, Ui_Dialog):
|
||||
self.title.setText(dynamic.get('catalog_last_used_title',
|
||||
_('My Books')))
|
||||
|
||||
# GwR *** Add option tabs for built-in formats
|
||||
# This code models #69 in calibre/gui2/dialogs/config/__init__.py
|
||||
|
||||
self.fmts, self.widgets = [], []
|
||||
|
||||
from calibre.customize.builtins import plugins as builtin_plugins
|
||||
@ -49,11 +46,12 @@ class Catalog(QDialog, Ui_Dialog):
|
||||
|
||||
name = plugin.name.lower().replace(' ', '_')
|
||||
if type(plugin) in builtin_plugins:
|
||||
#info("Adding widget for builtin Catalog plugin %s" % plugin.name)
|
||||
info("Adding widget for builtin Catalog plugin %s" % plugin.name)
|
||||
try:
|
||||
catalog_widget = __import__('calibre.gui2.catalog.'+name,
|
||||
fromlist=[1])
|
||||
pw = catalog_widget.PluginWidget()
|
||||
info("Initializing %s" % name)
|
||||
pw.initialize(name)
|
||||
pw.ICON = I('forward.svg')
|
||||
self.widgets.append(pw)
|
||||
@ -122,14 +120,14 @@ class Catalog(QDialog, Ui_Dialog):
|
||||
if self.sync.isEnabled():
|
||||
self.sync.setChecked(dynamic.get('catalog_sync_to_device', True))
|
||||
|
||||
self.format.currentIndexChanged.connect(self.format_changed)
|
||||
self.format.currentIndexChanged.connect(self.show_plugin_tab)
|
||||
self.show_plugin_tab(None)
|
||||
|
||||
|
||||
def show_plugin_tab(self, idx):
|
||||
cf = unicode(self.format.currentText()).lower()
|
||||
while self.tabs.count() > 1:
|
||||
self.tabs.remove(1)
|
||||
self.tabs.removeTab(1)
|
||||
for pw in self.widgets:
|
||||
if cf in pw.formats:
|
||||
self.tabs.addTab(pw, pw.TITLE)
|
||||
|
@ -1402,7 +1402,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
|
||||
dynamic.set('catalogs_to_be_synced', sync)
|
||||
self.status_bar.showMessage(_('Catalog generated.'), 3000)
|
||||
self.sync_catalogs()
|
||||
if job.fmt in ['CSV','XML']:
|
||||
if job.fmt not in ['EPUB','MOBI']:
|
||||
export_dir = choose_dir(self, _('Export Catalog Directory'),
|
||||
_('Select destination for %s.%s') % (job.catalog_title, job.fmt.lower()))
|
||||
if export_dir:
|
||||
|
@ -178,6 +178,7 @@ class Document(QWebPage):
|
||||
|
||||
def set_user_stylesheet(self):
|
||||
raw = config().parse().user_css
|
||||
raw = '::selection {background:#ffff00; color:#000;}\n'+raw
|
||||
data = 'data:text/css;charset=utf-8;base64,'
|
||||
data += b64encode(raw.encode('utf-8'))
|
||||
self.settings().setUserStyleSheetUrl(QUrl(data))
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -124,7 +124,7 @@ Convert e-books
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
.. |cei| image:: images/convert_ebooks.png
|
||||
|
||||
|cei| Ebooks can be converted from a number of formats into the LRF format (for the SONY Reader). Note that ebooks you purchase will typically have `Digital Rights Management <http://en.wikipedia.org/wiki/Digital_rights_management>`_ *(DRM)*. |app| will not convert these ebooks. For many DRM formats, it is easy to remove the DRM, but as this is illegal, you have to find tools to liberate your books yourself and then use |app| to convert them.
|
||||
|cei| Ebooks can be converted from a number of formats into the LRF format (for the SONY Reader). Note that ebooks you purchase will typically have `Digital Rights Management <http://bugs.calibre-ebook.com/wiki/DRM>`_ *(DRM)*. |app| will not convert these ebooks. For many DRM formats, it is easy to remove the DRM, but as this is illegal, you have to find tools to liberate your books yourself and then use |app| to convert them.
|
||||
|
||||
For most people, conversion should be a simple 1-click affair. But if you want to learn more about the conversion process, see :ref:`conversion`.
|
||||
|
||||
@ -134,7 +134,7 @@ The :guilabel:`Convert E-books` action has three variations, accessed by the arr
|
||||
|
||||
2. **Bulk convert**: This allows you to specify options only once to convert a number of ebooks in bulk.
|
||||
|
||||
3. **Set conversion defaults**: Allows you to set the default settings for future conversions.
|
||||
3. **Create catalog**: This action allow yous to generate a complete listing with all metadata of the books in your library, in several formats, like XML, CSV, EPUB and MOBI. The catalog will contain all the books showing in the library view currently, so you can use the search features to limit the books to be catalogued. In addition, if you select multiple books using the mouse, only those books will be added to the catalog. If you generate the catalog in an e-book format such as EPUB or MOBI, the next time you connect your e-book reader, the catalog will be automatically sent to the device.
|
||||
|
||||
.. _view:
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user