diff --git a/src/calibre/ebooks/oeb/transforms/flatcss.py b/src/calibre/ebooks/oeb/transforms/flatcss.py index bd76af811c..c726ae30c9 100644 --- a/src/calibre/ebooks/oeb/transforms/flatcss.py +++ b/src/calibre/ebooks/oeb/transforms/flatcss.py @@ -222,8 +222,8 @@ class CSSFlattener(object): if dyn_rescale is not None: fsize = self.fmap[_sbase] fsize *= dyn_rescale + cssdict['font-size'] = '%0.5fem'%(fsize/psize) psize = fsize - cssdict['font-size'] = '%0.5fpt'%(fsize) elif 'font-size' in cssdict or tag == 'body': fsize = self.fmap[style['font-size']] cssdict['font-size'] = "%0.5fem" % (fsize / psize) diff --git a/src/calibre/gui2/convert/pdf_output.py b/src/calibre/gui2/convert/pdf_output.py new file mode 100644 index 0000000000..2225b59436 --- /dev/null +++ b/src/calibre/gui2/convert/pdf_output.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- + +__license__ = 'GPL 3' +__copyright__ = '2009, John Schember ' +__docformat__ = 'restructuredtext en' + +from calibre.gui2.convert.pdf_output_ui import Ui_Form +from calibre.gui2.convert import Widget +from calibre.ebooks.pdf.pageoptions import PAPER_SIZES, ORIENTATIONS +from calibre.gui2.widgets import BasicComboModel + +paper_size_model = None +orientation_model = None + +class PluginWidget(Widget, Ui_Form): + + TITLE = _('PDF Output') + + def __init__(self, parent, get_option, get_help, db=None, book_id=None): + Widget.__init__(self, parent, 'pdf_output', ['paper_size', 'orientation']) + self.db, self.book_id = db, book_id + self.initialize_options(get_option, get_help, db, book_id) + + default_paper_size = self.opt_paper_size.currentText() + default_orientation = self.opt_orientation.currentText() + + global paper_size_model + if paper_size_model is None: + paper_size_model = BasicComboModel(PAPER_SIZES.keys()) + self.paper_size_model = paper_size_model + self.opt_paper_size.setModel(self.paper_size_model) + + default_index = self.opt_paper_size.findText(default_paper_size) + self.opt_paper_size.setCurrentIndex(default_index if default_index != -1 else 0) + + global orientation_model + if orientation_model is None: + orientation_model = BasicComboModel(ORIENTATIONS.keys()) + self.orientation_model = orientation_model + self.opt_orientation.setModel(self.orientation_model) + + default_index = self.opt_orientation.findText(default_orientation) + self.opt_orientation.setCurrentIndex(default_index if default_index != -1 else 0) + diff --git a/src/calibre/gui2/convert/pdf_output.ui b/src/calibre/gui2/convert/pdf_output.ui new file mode 100644 index 0000000000..ef29c55265 --- /dev/null +++ b/src/calibre/gui2/convert/pdf_output.ui @@ -0,0 +1,54 @@ + + + Form + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + + Paper Size: + + + + + + + + + + Orientation: + + + + + + + + + + Qt::Vertical + + + + 20 + 213 + + + + + + + + + diff --git a/src/calibre/gui2/convert/txt_output.py b/src/calibre/gui2/convert/txt_output.py new file mode 100644 index 0000000000..6c084b18ff --- /dev/null +++ b/src/calibre/gui2/convert/txt_output.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- + +__license__ = 'GPL 3' +__copyright__ = '2009, John Schember ' +__docformat__ = 'restructuredtext en' + +from calibre.gui2.convert.txt_output_ui import Ui_Form +from calibre.gui2.convert import Widget +from calibre.ebooks.txt.writer import TxtNewlines +from calibre.gui2.widgets import BasicComboModel + +newline_model = None + +class PluginWidget(Widget, Ui_Form): + + TITLE = _('TXT Output') + + def __init__(self, parent, get_option, get_help, db=None, book_id=None): + Widget.__init__(self, parent, 'txt_output', ['newline']) + self.db, self.book_id = db, book_id + self.initialize_options(get_option, get_help, db, book_id) + + default = self.opt_newline.currentText() + + global newline_model + if newline_model is None: + newline_model = BasicComboModel(TxtNewlines.NEWLINE_TYPES.keys()) + self.newline_model = newline_model + self.opt_newline.setModel(self.newline_model) + + default_index = self.opt_newline.findText(default) + self.opt_newline.setCurrentIndex(default_index if default_index != -1 else 0) + diff --git a/src/calibre/gui2/convert/txt_output.ui b/src/calibre/gui2/convert/txt_output.ui new file mode 100644 index 0000000000..368c8d7b8b --- /dev/null +++ b/src/calibre/gui2/convert/txt_output.ui @@ -0,0 +1,44 @@ + + + Form + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + + Newline Type: + + + + + + + + + + Qt::Vertical + + + + 20 + 246 + + + + + + + + + diff --git a/src/calibre/gui2/dialogs/config.py b/src/calibre/gui2/dialogs/config.py index faf749fc73..1550912e61 100644 --- a/src/calibre/gui2/dialogs/config.py +++ b/src/calibre/gui2/dialogs/config.py @@ -25,7 +25,7 @@ from calibre.customize.ui import initialized_plugins, is_disabled, enable_plugin disable_plugin, customize_plugin, \ plugin_customization, add_plugin, \ remove_plugin, input_format_plugins, \ - output_format_plugins + output_format_plugins, available_output_formats from calibre.utils.smtp import config as smtp_prefs from calibre.gui2.convert.look_and_feel import LookAndFeelWidget from calibre.gui2.convert.page_setup import PageSetupWidget @@ -391,6 +391,13 @@ class ConfigDialog(QDialog, Ui_Dialog): icons = config['toolbar_icon_size'] self.toolbar_button_size.setCurrentIndex(0 if icons == self.ICON_SIZES[0] else 1 if icons == self.ICON_SIZES[1] else 2) self.show_toolbar_text.setChecked(config['show_text_in_toolbar']) + + output_formats = sorted(available_output_formats()) + output_formats.remove('oeb') + for f in output_formats: + self.output_format.addItem(f) + default_index = self.output_format.findText(prefs['output_format']) + self.output_format.setCurrentIndex(default_index if default_index != -1 else 0) self.book_exts = sorted(BOOK_EXTENSIONS) for ext in self.book_exts: @@ -760,6 +767,7 @@ class ConfigDialog(QDialog, Ui_Dialog): p = {0:'normal', 1:'high', 2:'low'}[self.priority.currentIndex()] prefs['worker_process_priority'] = p prefs['read_file_metadata'] = bool(self.pdf_metadata.isChecked()) + prefs['output_format'] = self.output_format.currentText() config['save_to_disk_single_format'] = self.book_exts[self.single_format.currentIndex()] config['cover_flow_queue_length'] = self.cover_browse.value() prefs['language'] = str(self.language.itemData(self.language.currentIndex()).toString()) diff --git a/src/calibre/gui2/dialogs/config.ui b/src/calibre/gui2/dialogs/config.ui index ac432c52c0..4d8d64e151 100644 --- a/src/calibre/gui2/dialogs/config.ui +++ b/src/calibre/gui2/dialogs/config.ui @@ -1,8 +1,9 @@ - + + Kovid Goyal Dialog - - + + 0 0 @@ -10,111 +11,111 @@ 557 - + Configuration - - + + :/images/config.svg:/images/config.svg - - - + + + - - - + + + 1 0 - + 75 true - + QAbstractItemView::NoEditTriggers - + true - + false - + 48 48 - + QAbstractItemView::ScrollPerItem - + QAbstractItemView::ScrollPerPixel - + QListView::TopToBottom - + 20 - + QListView::ListMode - - - + + + 100 0 - + 0 - - + + - + - - + + 16777215 70 - + &Location of ebooks (The ebooks are stored in folders sorted by author and metadata is stored in the file metadata.db) - + true - + location - + - + - - + + Browse for the new database location - + ... - - + + :/images/mimetypes/dir.svg:/images/mimetypes/dir.svg @@ -124,127 +125,137 @@ - - + + Show notification when &new version is available - - + + If you disable this setting, metadata is guessed from the filename instead. This can be configured in the Advanced section. - + Read &metadata from files - + true - - - - + + + + Format for &single file save: - + single_format - - + + - - - + + + Default network &timeout: - + timeout - - - + + + Set the default timeout for network fetches (i.e. anytime we go out to the internet to get information) - + seconds - + 2 - + 120 - + 5 - - + + - - - + + + Choose &language (requires restart): - + language - - + + - + Normal - + High - + Low - - - + + + Job &priority: - + priority + + + + Output Format: + + + + + + - - + + Frequently used directories - - - + + + - - + + true - + 22 22 @@ -253,13 +264,13 @@ - + - + Qt::Vertical - + 20 40 @@ -268,25 +279,25 @@ - - + + Add a directory to the frequently used directories list - + ... - - + + :/images/plus.svg:/images/plus.svg - + Qt::Vertical - + 20 40 @@ -295,25 +306,25 @@ - - + + Remove a directory from the frequently used directories list - + ... - - + + :/images/list_remove.svg:/images/list_remove.svg - + Qt::Vertical - + 20 40 @@ -330,111 +341,111 @@ - - + + - - + + Use &Roman numerals for series number - + true - - + + Enable system &tray icon (needs restart) - - + + Show &notifications in system tray - - + + Show cover &browser in a separate window (needs restart) - - + + Automatically send downloaded &news to ebook reader - - + + &Delete news from library when it is automatically sent to reader - + - - + + &Number of covers to show in browse mode (needs restart): - + cover_browse - + - - + + Toolbar - - - + + + - + Large - + Medium - + Small - - - + + + &Button size in toolbar - + toolbar_button_size - - - + + + Show &text in toolbar buttons - + true @@ -443,44 +454,44 @@ - + - - + + Select visible &columns in library view - + - + - - + + true - + QAbstractItemView::SelectRows - + - - + + ... - - + + :/images/arrow-up.svg:/images/arrow-up.svg - - + + Qt::Vertical - + 20 40 @@ -489,12 +500,12 @@ - - + + ... - - + + :/images/arrow-down.svg:/images/arrow-down.svg @@ -507,17 +518,17 @@ - - + + Use internal &viewer for: - - - - + + + + true - + QAbstractItemView::NoSelection @@ -538,99 +549,99 @@ - - - - - + + + + + calibre can send your books to you (or your reader) by email - + true - - + + - - + + Send email &from: - + email_from - - - <p>This is what will be present in the From: field of emails sent by calibre.<br> Set it to your email address + + + <p>This is what will be present in the From: field of emails sent by calibre.<br> Set it to your email address - - + + - - + + QAbstractItemView::SingleSelection - + QAbstractItemView::SelectRows - + - - + + Add an email address to which to send books - + &Add email - - + + :/images/plus.svg:/images/plus.svg - + 24 24 - + Qt::ToolButtonTextUnderIcon - - + + Make &default - - + + &Remove email - - + + :/images/minus.svg:/images/minus.svg - + 24 24 - + Qt::ToolButtonTextUnderIcon @@ -639,155 +650,155 @@ - - - - <p>A mail server is useful if the service you are sending mail to only accepts email from well know mail services. + + + + <p>A mail server is useful if the service you are sending mail to only accepts email from well know mail services. - + Mail &Server - - - - - calibre can <b>optionally</b> use a server to send mail + + + + + calibre can <b>optionally</b> use a server to send mail - + true - - - + + + &Hostname: - + relay_host - - - + + + The hostname of your mail server. For e.g. smtp.gmail.com - - + + - - + + &Port: - + relay_port - - + + The port your mail server listens for connections on. The default is 25 - + 1 - + 65555 - + 25 - - - + + + &Username: - + relay_username - - - + + + Your username on the mail server - - - + + + &Password: - + relay_password - - - + + + Your password on the mail server - + QLineEdit::Password - - - + + + &Show - - - + + + &Encryption: - + relay_tls - - - + + + Use TLS encryption when connecting to the mail server. This is the most common. - + &TLS - + true - - - + + + Use SSL encryption when connecting to the mail server. - + &SSL - - - + + + Qt::Horizontal - + 40 20 @@ -798,31 +809,31 @@ - - + + - - + + Use Gmail - - + + :/images/gmail_logo.png:/images/gmail_logo.png - + 48 48 - + Qt::ToolButtonTextUnderIcon - - + + &Test email @@ -831,16 +842,16 @@ - - + + - + - + Qt::Horizontal - + 40 20 @@ -849,21 +860,21 @@ - - + + Free unused diskspace from the database - + &Compact database - + Qt::Horizontal - + 40 20 @@ -874,17 +885,17 @@ - - + + &Metadata from file name - + - + Qt::Vertical - + 20 40 @@ -897,96 +908,96 @@ - - + + - - + + calibre contains a network server that allows you to access your book collection using a browser from anywhere in the world. Any changes to the settings will only take effect after a server restart. - + true - - - - + + + + Server &port: - + port - - - + + + 1025 - + 16000 - + 8080 - - - + + + &Username: - + username - - + + - - - + + + &Password: - + password - - - + + + If you leave the password blank, anyone will be able to access your book collection using the web interface. - - - + + + &Show password - - - + + + The maximum size (widthxheight) for displayed covers. Larger covers are resized. - + - - - + + + Max. &cover size: - + max_cover_size @@ -994,27 +1005,27 @@ - + - - + + &Start Server - - + + St&op Server - - + + Qt::Horizontal - + 40 20 @@ -1023,8 +1034,8 @@ - - + + &Test Server @@ -1032,25 +1043,25 @@ - - + + Run server &automatically on startup - - + + View &server logs - - + + Qt::Vertical - + 20 40 @@ -1059,21 +1070,21 @@ - - + + If you want to use the content server to access your ebook collection on your iphone with Stanza, you will need to add the URL http://myhostname:8080/stanza as a new catalog in the stanza reader on your iphone. Here myhostname should be the fully qualified hostname or the IP address of this computer. - + true - - + + Qt::Vertical - + 20 40 @@ -1083,53 +1094,53 @@ - - + + - - + + Here you can customize the behavior of Calibre by controlling what plugins it uses. - + true - - + + 32 32 - + true - + true - + - - + + Enable/&Disable plugin - - + + &Customize plugin - - + + &Remove plugin @@ -1137,33 +1148,33 @@ - - + + Add new plugin - + - + - - + + Plugin &file: - + plugin_path - + - - + + ... - - + + :/images/document_open.svg:/images/document_open.svg @@ -1171,13 +1182,13 @@ - + - - + + Qt::Horizontal - + 40 20 @@ -1186,8 +1197,8 @@ - - + + &Add @@ -1203,12 +1214,12 @@ - - - + + + Qt::Horizontal - + QDialogButtonBox::Cancel|QDialogButtonBox::Ok @@ -1216,7 +1227,7 @@ - + @@ -1225,11 +1236,11 @@ Dialog accept() - + 239 558 - + 157 274 @@ -1241,11 +1252,11 @@ Dialog reject() - + 307 558 - + 286 274 diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index 6bea660294..6840f4d7a8 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -136,14 +136,6 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): SIGNAL('location_selected(PyQt_PyObject)'), self.location_selected) - self.output_formats = sorted(['EPUB', 'MOBI', 'LRF']) - for f in self.output_formats: - self.output_format.addItem(f) - self.output_format.setCurrentIndex(self.output_formats.index( - prefs['output_format'])) - self.connect(self.output_format, SIGNAL('currentIndexChanged(QString)'), - self.change_output_format, Qt.QueuedConnection) - ####################### Vanity ######################## self.vanity_template = _('

For help visit %s.kovidgoyal.net' @@ -266,8 +258,6 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): setPopupMode(QToolButton.MenuButtonPopup) self.tool_bar.setContextMenuPolicy(Qt.PreventContextMenu) - QObject.connect(self.config_button, - SIGNAL('clicked(bool)'), self.do_config) self.connect(self.preferences_action, SIGNAL('triggered(bool)'), self.do_config) self.connect(self.action_preferences, SIGNAL('triggered(bool)'), @@ -452,12 +442,6 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): window.show() setattr(window, '__systray_minimized', False) - - def change_output_format(self, x): - of = unicode(x).strip() - if of != prefs['output_format']: - prefs.set('output_format', of) - def test_server(self, *args): if self.content_server.exception is not None: error_dialog(self, _('Failed to start content server'), @@ -1057,7 +1041,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): rows = [x.row() for x in \ self.library_view.selectionModel().selectedRows()] jobs, changed, bad = convert_bulk_ebook(self, - self.library_view.model().db, row_ids) + self.library_view.model().db, row_ids, out_format=prefs['output_format']) for func, args, desc, fmt, id, temp_files in jobs: if id not in bad: job = self.job_manager.run_job(Dispatcher(self.book_converted), @@ -1076,7 +1060,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): rows = [x.row() for x in \ self.library_view.selectionModel().selectedRows()] jobs, changed, bad = convert_single_ebook(self, - self.library_view.model().db, row_ids) + self.library_view.model().db, row_ids, out_format=prefs['output_format']) for func, args, desc, fmt, id, temp_files in jobs: if id not in bad: job = self.job_manager.run_job(Dispatcher(self.book_converted), diff --git a/src/calibre/gui2/main.ui b/src/calibre/gui2/main.ui index 24ba2a1c7a..89bc2dfa79 100644 --- a/src/calibre/gui2/main.ui +++ b/src/calibre/gui2/main.ui @@ -1,8 +1,9 @@ - + + Kovid Goyal MainWindow - - + + 0 0 @@ -10,331 +11,279 @@ 822 - - + + 0 0 - + Qt::NoContextMenu - + __appname__ - - + + :/library:/library - - - - + + + + - - - + + + 0 0 - + 16777215 100 - + Qt::ScrollBarAlwaysOff - + Qt::ScrollBarAsNeeded - + QAbstractItemView::NoEditTriggers - + true - + true - + QAbstractItemView::NoSelection - + QAbstractItemView::SelectRows - + 40 40 - + QListView::Static - + QListView::LeftToRight - + 175 90 - + QListView::ListMode - + true - - + + PointingHandCursor - + ... - - + + :/images/donate.svg:/images/donate.svg - + 64 64 - + true - + - - - + + + 0 0 - + 16777215 90 - + - + Qt::RichText - + true - - - - - - Output: - - - - - - - Set the output format that is used when converting ebooks and downloading news - - - - - - - - + + + 6 - + 0 - - + + Advanced search - + ... - - + + :/images/search.svg:/images/search.svg - + Alt+S - - + + &Search: - + search - - + + true - - + + 1 0 - + false - - Search the list of books by title or author<br><br>Words separated by spaces are ANDed + + Search the list of books by title or author<br><br>Words separated by spaces are ANDed - - Search the list of books by title, author, publisher, tags and comments<br><br>Words separated by spaces are ANDed + + Search the list of books by title, author, publisher, tags and comments<br><br>Words separated by spaces are ANDed - + false - + - + true - - + + Reset Quick Search - + ... - - + + :/images/clear_left.svg:/images/clear_left.svg - - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - 20 - 20 - - - - - - - - Configuration - - - ... - - - - :/images/config.svg:/images/config.svg - - - - - - - + + + + 100 100 - + 3 - - + + - + - + - - + + Match any - + false - - + + Match all - + true - - + + Sort by &popularity - - + + true - + true - + true - + true @@ -342,35 +291,35 @@ - - - + + + 100 10 - + true - + true - + false - + QAbstractItemView::DragDrop - + true - + QAbstractItemView::SelectRows - + false - + false @@ -379,114 +328,114 @@ - - - - - - + + + + + + 100 10 - + true - + true - + false - + QAbstractItemView::DragDrop - + true - + QAbstractItemView::SelectRows - + false - + false - - - - - - + + + + + + 10 10 - + true - + true - + false - + QAbstractItemView::DragDrop - + true - + QAbstractItemView::SelectRows - + false - + false - - - - - - + + + + + + 10 10 - + true - + true - + false - + QAbstractItemView::DragDrop - + true - + QAbstractItemView::SelectRows - + false - + false @@ -497,225 +446,225 @@ - - + + 0 0 - + Qt::PreventContextMenu - + false - + Qt::Horizontal - + 48 48 - + Qt::ToolButtonTextUnderIcon - + TopToolBarArea - + false - - - - - - - - - - - + + + + + + + + + + + - - + + true - - - + + + :/images/add_book.svg:/images/add_book.svg - + Add books - + A - + false - - - + + + :/images/trash.svg:/images/trash.svg - + Remove books - + Remove books - + Del - - - + + + :/images/edit_input.svg:/images/edit_input.svg - + Edit meta information - + E - + false - - + + false - - + + :/images/sync.svg:/images/sync.svg - + Send to device - - - + + + :/images/save.svg:/images/save.svg - + Save to disk - + S - - - + + + :/images/news.svg:/images/news.svg - + Fetch news - + F - - - + + + :/images/convert.svg:/images/convert.svg - + Convert E-books - + C - - - + + + :/images/view.svg:/images/view.svg - + View - + V - - - + + + :/images/document_open.svg:/images/document_open.svg - + Open containing folder - - - + + + :/images/dialog_information.svg:/images/dialog_information.svg - + Show book details - - - + + + :/images/user_profile.svg:/images/user_profile.svg - + Books by same author - - - + + + :/images/books_in_series.svg:/images/books_in_series.svg - + Books in this series - - - + + + :/images/publisher.png:/images/publisher.png - + Books by this publisher - - - + + + :/images/tags.svg:/images/tags.svg - + Books with the same tags - - - + + + :/images/config.svg:/images/config.svg - + Preferences - + Configure calibre - + Ctrl+P @@ -748,7 +697,7 @@ - + @@ -757,11 +706,11 @@ search clear() - + 787 215 - + 755 213 diff --git a/src/calibre/gui2/tools.py b/src/calibre/gui2/tools.py index ceeee60ab5..b8dbbd5eba 100644 --- a/src/calibre/gui2/tools.py +++ b/src/calibre/gui2/tools.py @@ -72,7 +72,7 @@ def convert_single_ebook(parent, db, book_ids, auto_conversion=False, out_format return jobs, changed, bad -def convert_bulk_ebook(parent, db, book_ids): +def convert_bulk_ebook(parent, db, book_ids, out_format=None): changed = False jobs = [] bad = [] @@ -82,7 +82,7 @@ def convert_bulk_ebook(parent, db, book_ids): return None, None, None parent.status_bar.showMessage(_('Starting conversion of %d books') % total, 2000) - d = BulkConfig(parent, db) + d = BulkConfig(parent, db, out_format) if d.exec_() != QDialog.Accepted: return jobs, changed, bad diff --git a/src/calibre/web/feeds/input.py b/src/calibre/web/feeds/input.py index e0a8b807c8..ee003be0da 100644 --- a/src/calibre/web/feeds/input.py +++ b/src/calibre/web/feeds/input.py @@ -18,9 +18,13 @@ class RecipeInput(InputFormatPlugin): file_types = set(['recipe']) recommendations = set([ - ('chapter_mark', 'none', OptionRecommendation.HIGH), + ('chapter', None, OptionRecommendation.HIGH), ('dont_split_on_page_breaks', True, OptionRecommendation.HIGH), ('use_auto_toc', False, OptionRecommendation.HIGH), + ('input_encoding', None, OptionRecommendation.HIGH), + ('input_profile', 'default', OptionRecommendation.HIGH), + ('page_breaks_before', None, OptionRecommendation.HIGH), + ('insert_metadata', False, OptionRecommendation.HIGH), ]) options = set([ diff --git a/src/calibre/web/feeds/news.py b/src/calibre/web/feeds/news.py index 36e5829fcd..3f6b9b9ae1 100644 --- a/src/calibre/web/feeds/news.py +++ b/src/calibre/web/feeds/news.py @@ -579,8 +579,9 @@ class BasicNewsRecipe(Recipe): def feeds2index(self, feeds): templ = templates.IndexTemplate() + css = self.template_css + '\n\n' +(self.extra_css if self.extra_css else '') return templ.generate(self.title, self.timefmt, feeds, - extra_css=self.extra_css).render(doctype='xhtml') + extra_css=css).render(doctype='xhtml') @classmethod def description_limiter(cls, src): @@ -631,8 +632,9 @@ class BasicNewsRecipe(Recipe): templ = templates.FeedTemplate() + css = self.template_css + '\n\n' +(self.extra_css if self.extra_css else '') return templ.generate(feed, self.description_limiter, - extra_css=self.extra_css).render(doctype='xhtml') + extra_css=css).render(doctype='xhtml') def _fetch_article(self, url, dir, f, a, num_of_feeds): diff --git a/src/calibre/web/feeds/recipes/recipe_dna.py b/src/calibre/web/feeds/recipes/recipe_dna.py index 6ec9ba4665..a335fd5655 100644 --- a/src/calibre/web/feeds/recipes/recipe_dna.py +++ b/src/calibre/web/feeds/recipes/recipe_dna.py @@ -5,12 +5,13 @@ import re from calibre.web.feeds.news import BasicNewsRecipe class DNAIndia(BasicNewsRecipe): - + title = 'DNA India' description = 'Mumbai news, India news, World news, breaking news' __author__ = 'Kovid Goyal' language = _('English') - + encoding = 'cp1252' + feeds = [ ('Top News', 'http://www.dnaindia.com/syndication/rss_topnews.xml'), ('Popular News', 'http://www.dnaindia.com/syndication/rss_popular.xml'), @@ -21,21 +22,21 @@ class DNAIndia(BasicNewsRecipe): ('Money', 'http://www.dnaindia.com/syndication/rss,catid-4.xml'), ('Sports', 'http://www.dnaindia.com/syndication/rss,catid-6.xml'), ('After Hours', 'http://www.dnaindia.com/syndication/rss,catid-7.xml'), - ('Digital Life', 'http://www.dnaindia.com/syndication/rss,catid-1089741.xml'), + ('Digital Life', 'http://www.dnaindia.com/syndication/rss,catid-1089741.xml'), ] remove_tags = [{'id':'footer'}, {'class':['bottom', 'categoryHead']}] - + def print_version(self, url): match = re.search(r'newsid=(\d+)', url) if not match: return url return 'http://www.dnaindia.com/dnaprint.asp?newsid='+match.group(1) - + def postprocess_html(self, soup, first_fetch): for t in soup.findAll(['table', 'tr', 'td']): t.name = 'div' - + a = soup.find(href='http://www.3dsyndication.com/') if a is not None: a.parent.extract() - return soup \ No newline at end of file + return soup diff --git a/src/calibre/web/feeds/recipes/recipe_newsweek.py b/src/calibre/web/feeds/recipes/recipe_newsweek.py index 6f47019f46..3197989da8 100644 --- a/src/calibre/web/feeds/recipes/recipe_newsweek.py +++ b/src/calibre/web/feeds/recipes/recipe_newsweek.py @@ -5,7 +5,6 @@ __copyright__ = '2008, Kovid Goyal ' import re, string, time from calibre import strftime from calibre.web.feeds.news import BasicNewsRecipe -from calibre.ebooks.BeautifulSoup import BeautifulSoup class Newsweek(BasicNewsRecipe): @@ -14,15 +13,20 @@ class Newsweek(BasicNewsRecipe): description = 'Weekly news and current affairs in the US' no_stylesheets = True language = _('English') - - extra_css = '#content { font:serif 12pt; }\n.story {font:12pt}\n.HorizontalHeader {font:18pt}\n.deck {font:16pt}' + + extra_css = ''' + #content { font-size:normal; font-family: serif } + .story { font-size:normal } + .HorizontalHeader {font-size:xx-large} + .deck {font-size:x-large} + ''' keep_only_tags = [dict(name='div', id='content')] remove_tags = [ dict(name=['script', 'noscript']), dict(name='div', attrs={'class':['ad', 'SocialLinks', 'SocialLinksDiv', - 'channel', 'bot', 'nav', 'top', - 'EmailArticleBlock', + 'channel', 'bot', 'nav', 'top', + 'EmailArticleBlock', 'comments-and-social-links-wrapper', 'inline-social-links-wrapper', 'inline-social-links', @@ -31,14 +35,14 @@ class Newsweek(BasicNewsRecipe): dict(id=['ToolBox', 'EmailMain', 'EmailArticle', 'comment-box', 'nw-comments']) ] - + recursions = 1 match_regexps = [r'http://www.newsweek.com/id/\S+/page/\d+'] - - + + def get_sections(self, soup): sections = [] - + def process_section(img): articles = [] match = re.search(r'label_([^_.]+)', img['src']) @@ -48,25 +52,25 @@ class Newsweek(BasicNewsRecipe): if title in ['coverstory', 'more', 'tipsheet']: return title = string.capwords(title) - + for a in img.parent.findAll('a', href=True): art, href = a.string, a['href'] if not re.search('\d+$', href) or not art or 'Preview Article' in art: continue articles.append({ - 'title':art, 'url':href, 'description':'', - 'content':'', 'date':'' + 'title':art, 'url':href, 'description':'', + 'content':'', 'date':'' }) sections.append((title, articles)) - + img.parent.extract() for img in soup.findAll(src=re.compile('/label_')): process_section(img) - + return sections - + def parse_index(self): soup = self.get_current_issue() if not soup: @@ -78,10 +82,10 @@ class Newsweek(BasicNewsRecipe): if match is not None: self.timefmt = strftime(' [%d %b, %Y]', time.strptime(match.group(1), '%y%m%d')) self.cover_url = small.replace('coversmall', 'coverlarge') - + sections = self.get_sections(soup) sections.insert(0, ('Main articles', [])) - + for tag in soup.findAll('h5'): a = tag.find('a', href=True) if a is not None: @@ -97,8 +101,8 @@ class Newsweek(BasicNewsRecipe): if art['title'] and art['url']: sections[0][1].append(art) return sections - - + + def postprocess_html(self, soup, first_fetch): divs = list(soup.findAll('div', 'pagination')) if not divs: @@ -106,8 +110,8 @@ class Newsweek(BasicNewsRecipe): divs[0].extract() if len(divs) > 1: soup.find('body')['style'] = 'page-break-after:avoid' - divs[1].extract() - + divs[1].extract() + h1 = soup.find('h1') if h1: h1.extract() @@ -116,12 +120,12 @@ class Newsweek(BasicNewsRecipe): else: soup.find('body')['style'] = 'page-break-before:always; page-break-after:avoid;' return soup - + def get_current_issue(self): #from urllib2 import urlopen # For some reason mechanize fails - #home = urlopen('http://www.newsweek.com').read() + #home = urlopen('http://www.newsweek.com').read() soup = self.index_to_soup('http://www.newsweek.com')#BeautifulSoup(home) img = soup.find('img', alt='Current Magazine') if img and img.parent.has_key('href'): return self.index_to_soup(img.parent['href']) - + diff --git a/src/calibre/web/fetch/simple.py b/src/calibre/web/fetch/simple.py index cbe048a011..0920161316 100644 --- a/src/calibre/web/fetch/simple.py +++ b/src/calibre/web/fetch/simple.py @@ -53,9 +53,15 @@ def save_soup(soup, target): ns = BeautifulSoup('') nm = ns.find('meta') metas = soup.findAll('meta', content=True) + added = False for meta in metas: if 'charset' in meta.get('content', '').lower(): meta.replaceWith(nm) + added = True + if not added: + head = soup.find('head') + if head is not None: + head.insert(0, nm) selfdir = os.path.dirname(target) @@ -67,6 +73,7 @@ def save_soup(soup, target): html = unicode(soup) with open(target, 'wb') as f: + idx = html.find('hoping') f.write(html.encode('utf-8')) class response(str):