mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 18:54:09 -04:00
FB2 Output: Option to set the FB2 genre explicitly. Fix #743178 (BasicNewsRecipe.delay must be an integer). Run smartypants on textile input.
This commit is contained in:
commit
197d37f358
@ -111,6 +111,7 @@ class FB2MLizer(object):
|
||||
metadata['lang'] = u'en'
|
||||
metadata['id'] = None
|
||||
metadata['cover'] = self.get_cover()
|
||||
metadata['genre'] = self.opts.fb2_genre
|
||||
|
||||
metadata['author'] = u''
|
||||
for auth in self.oeb_book.metadata.creator:
|
||||
@ -159,7 +160,7 @@ class FB2MLizer(object):
|
||||
return u'<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:xlink="http://www.w3.org/1999/xlink">' \
|
||||
'<description>' \
|
||||
'<title-info>' \
|
||||
'<genre>antique</genre>' \
|
||||
'<genre>%(genre)s</genre>' \
|
||||
'%(author)s' \
|
||||
'<book-title>%(title)s</book-title>' \
|
||||
'%(cover)s' \
|
||||
|
@ -15,6 +15,133 @@ class FB2Output(OutputFormatPlugin):
|
||||
author = 'John Schember'
|
||||
file_type = 'fb2'
|
||||
|
||||
FB2_GENRES = [
|
||||
# Science Fiction & Fantasy
|
||||
'sf_history', # Alternative history
|
||||
'sf_action', # Action
|
||||
'sf_epic', # Epic
|
||||
'sf_heroic', # Heroic
|
||||
'sf_detective', # Detective
|
||||
'sf_cyberpunk', # Cyberpunk
|
||||
'sf_space', # Space
|
||||
'sf_social', # Social#philosophical
|
||||
'sf_horror', # Horror & mystic
|
||||
'sf_humor', # Humor
|
||||
'sf_fantasy', # Fantasy
|
||||
'sf', # Science Fiction
|
||||
# Detectives & Thrillers
|
||||
'det_classic', # Classical detectives
|
||||
'det_police', # Police Stories
|
||||
'det_action', # Action
|
||||
'det_irony', # Ironical detectives
|
||||
'det_history', # Historical detectives
|
||||
'det_espionage', # Espionage detectives
|
||||
'det_crime', # Crime detectives
|
||||
'det_political', # Political detectives
|
||||
'det_maniac', # Maniacs
|
||||
'det_hard', # Hard#boiled
|
||||
'thriller', # Thrillers
|
||||
'detective', # Detectives
|
||||
# Prose
|
||||
'prose_classic', # Classics prose
|
||||
'prose_history', # Historical prose
|
||||
'prose_contemporary', # Contemporary prose
|
||||
'prose_counter', # Counterculture
|
||||
'prose_rus_classic', # Russial classics prose
|
||||
'prose_su_classics', # Soviet classics prose
|
||||
# Romance
|
||||
'love_contemporary', # Contemporary Romance
|
||||
'love_history', # Historical Romance
|
||||
'love_detective', # Detective Romance
|
||||
'love_short', # Short Romance
|
||||
'love_erotica', # Erotica
|
||||
# Adventure
|
||||
'adv_western', # Western
|
||||
'adv_history', # History
|
||||
'adv_indian', # Indians
|
||||
'adv_maritime', # Maritime Fiction
|
||||
'adv_geo', # Travel & geography
|
||||
'adv_animal', # Nature & animals
|
||||
'adventure', # Other
|
||||
# Children's
|
||||
'child_tale', # Fairy Tales
|
||||
'child_verse', # Verses
|
||||
'child_prose', # Prose
|
||||
'child_sf', # Science Fiction
|
||||
'child_det', # Detectives & Thrillers
|
||||
'child_adv', # Adventures
|
||||
'child_education', # Educational
|
||||
'children', # Other
|
||||
# Poetry & Dramaturgy
|
||||
'poetry', # Poetry
|
||||
'dramaturgy', # Dramaturgy
|
||||
# Antique literature
|
||||
'antique_ant', # Antique
|
||||
'antique_european', # European
|
||||
'antique_russian', # Old russian
|
||||
'antique_east', # Old east
|
||||
'antique_myths', # Myths. Legends. Epos
|
||||
'antique', # Other
|
||||
# Scientific#educational
|
||||
'sci_history', # History
|
||||
'sci_psychology', # Psychology
|
||||
'sci_culture', # Cultural science
|
||||
'sci_religion', # Religious studies
|
||||
'sci_philosophy', # Philosophy
|
||||
'sci_politics', # Politics
|
||||
'sci_business', # Business literature
|
||||
'sci_juris', # Jurisprudence
|
||||
'sci_linguistic', # Linguistics
|
||||
'sci_medicine', # Medicine
|
||||
'sci_phys', # Physics
|
||||
'sci_math', # Mathematics
|
||||
'sci_chem', # Chemistry
|
||||
'sci_biology', # Biology
|
||||
'sci_tech', # Technical
|
||||
'science', # Other
|
||||
# Computers & Internet
|
||||
'comp_www', # Internet
|
||||
'comp_programming', # Programming
|
||||
'comp_hard', # Hardware
|
||||
'comp_soft', # Software
|
||||
'comp_db', # Databases
|
||||
'comp_osnet', # OS & Networking
|
||||
'computers', # Other
|
||||
# Reference
|
||||
'ref_encyc', # Encyclopedias
|
||||
'ref_dict', # Dictionaries
|
||||
'ref_ref', # Reference
|
||||
'ref_guide', # Guidebooks
|
||||
'reference', # Other
|
||||
# Nonfiction
|
||||
'nonf_biography', # Biography & Memoirs
|
||||
'nonf_publicism', # Publicism
|
||||
'nonf_criticism', # Criticism
|
||||
'design', # Art & design
|
||||
'nonfiction', # Other
|
||||
# Religion & Inspiration
|
||||
'religion_rel', # Religion
|
||||
'religion_esoterics', # Esoterics
|
||||
'religion_self', # Self#improvement
|
||||
'religion', # Other
|
||||
# Humor
|
||||
'humor_anecdote', # Anecdote (funny stories)
|
||||
'humor_prose', # Prose
|
||||
'humor_verse', # Verses
|
||||
'humor', # Other
|
||||
# Home & Family
|
||||
'home_cooking', # Cooking
|
||||
'home_pets', # Pets
|
||||
'home_crafts', # Hobbies & Crafts
|
||||
'home_entertain', # Entertaining
|
||||
'home_health', # Health
|
||||
'home_garden', # Garden
|
||||
'home_diy', # Do it yourself
|
||||
'home_sport', # Sports
|
||||
'home_sex', # Erotica & sex
|
||||
'home', # Other
|
||||
]
|
||||
|
||||
options = set([
|
||||
OptionRecommendation(name='sectionize',
|
||||
recommended_value='files', level=OptionRecommendation.LOW,
|
||||
@ -25,6 +152,11 @@ class FB2Output(OutputFormatPlugin):
|
||||
'A value of "Table of Contents" turns the entries in the Table of Contents into titles and creates sections; '
|
||||
'if it fails, adjust the "Structure Detection" and/or "Table of Contents" settings '
|
||||
'(turn on "Force use of auto-generated Table of Contents).')),
|
||||
OptionRecommendation(name='fb2_genre',
|
||||
recommended_value='antique', level=OptionRecommendation.LOW,
|
||||
choices=FB2_GENRES,
|
||||
help=_('Genre for the book. Choices: %s\n\n See: ' % FB2_GENRES) + 'http://www.fictionbook.org/index.php/Eng:FictionBook_2.1_genres ' \
|
||||
+ _('for a complete list with descriptions.')),
|
||||
])
|
||||
|
||||
def convert(self, oeb_book, output_path, input_plugin, opts, log):
|
||||
|
@ -64,6 +64,8 @@ import re
|
||||
import uuid
|
||||
from urlparse import urlparse
|
||||
|
||||
from calibre.utils.smartypants import smartyPants
|
||||
|
||||
def _normalize_newlines(string):
|
||||
out = re.sub(r'\r\n', '\n', string)
|
||||
out = re.sub(r'\n{3,}', '\n\n', out)
|
||||
@ -262,10 +264,9 @@ class Textile(object):
|
||||
self.rel = ' rel="%s"' % rel
|
||||
|
||||
text = self.getRefs(text)
|
||||
|
||||
text = self.block(text, int(head_offset))
|
||||
|
||||
text = self.retrieve(text)
|
||||
text = smartyPants(text, 'q')
|
||||
|
||||
return text
|
||||
|
||||
|
@ -165,7 +165,8 @@ class TXTInput(InputFormatPlugin):
|
||||
elif options.formatting_type == 'textile':
|
||||
log.debug('Running text through textile conversion...')
|
||||
html = convert_textile(txt)
|
||||
#setattr(options, 'smarten_punctuation', True)
|
||||
# Textile input already runs smartypants
|
||||
options.smarten_punctuation = False
|
||||
else:
|
||||
log.debug('Running text through basic conversion...')
|
||||
flow_size = getattr(options, 'flow_size', 0)
|
||||
|
@ -17,8 +17,10 @@ class PluginWidget(Widget, Ui_Form):
|
||||
ICON = I('mimetypes/fb2.png')
|
||||
|
||||
def __init__(self, parent, get_option, get_help, db=None, book_id=None):
|
||||
Widget.__init__(self, parent, ['sectionize'])
|
||||
Widget.__init__(self, parent, ['sectionize', 'fb2_genre'])
|
||||
self.db, self.book_id = db, book_id
|
||||
for x in ('toc', 'files', 'nothing'):
|
||||
self.opt_sectionize.addItem(x)
|
||||
for x in get_option('fb2_genre').option.choices:
|
||||
self.opt_fb2_genre.addItem(x)
|
||||
self.initialize_options(get_option, get_help, db, book_id)
|
||||
|
@ -14,7 +14,7 @@
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<item row="2" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@ -44,6 +44,16 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Genre</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="opt_fb2_genre"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
|
@ -71,7 +71,8 @@ class BasicNewsRecipe(Recipe):
|
||||
#: Number of levels of links to follow on article webpages
|
||||
recursions = 0
|
||||
|
||||
#: Delay between consecutive downloads in seconds
|
||||
#: Delay between consecutive downloads in seconds. The argument may be a
|
||||
#: floating point number to indicate a more precise time.
|
||||
delay = 0
|
||||
|
||||
#: Publication type
|
||||
|
@ -486,7 +486,7 @@ def option_parser(usage=_('%prog URL\n\nWhere URL is for example http://google.c
|
||||
type='int', dest='max_recursions')
|
||||
parser.add_option('-n', '--max-files', default=sys.maxint, type='int', dest='max_files',
|
||||
help=_('The maximum number of files to download. This only applies to files from <a href> tags. Default is %default'))
|
||||
parser.add_option('--delay', default=0, dest='delay', type='int',
|
||||
parser.add_option('--delay', default=0, dest='delay', type='float',
|
||||
help=_('Minimum interval in seconds between consecutive fetches. Default is %default s'))
|
||||
parser.add_option('--encoding', default=None,
|
||||
help=_('The character encoding for the websites you are trying to download. The default is to try and guess the encoding.'))
|
||||
|
Loading…
x
Reference in New Issue
Block a user