mirror of
https://github.com/gryf/ebook-converter.git
synced 2026-01-01 07:22:26 +01:00
More cleanup
This commit is contained in:
@@ -820,21 +820,6 @@ plugins += input_profiles + output_profiles
|
||||
#]
|
||||
|
||||
|
||||
# }}}
|
||||
|
||||
# New metadata download plugins {{{
|
||||
#from ebook_converter.ebooks.metadata.sources.google import GoogleBooks
|
||||
#from ebook_converter.ebooks.metadata.sources.amazon import Amazon
|
||||
#from ebook_converter.ebooks.metadata.sources.edelweiss import Edelweiss
|
||||
#from ebook_converter.ebooks.metadata.sources.openlibrary import OpenLibrary
|
||||
#from ebook_converter.ebooks.metadata.sources.overdrive import OverDrive
|
||||
#from ebook_converter.ebooks.metadata.sources.douban import Douban
|
||||
#from ebook_converter.ebooks.metadata.sources.ozon import Ozon
|
||||
#from ebook_converter.ebooks.metadata.sources.google_images import GoogleImages
|
||||
#from ebook_converter.ebooks.metadata.sources.big_book_search import BigBookSearch
|
||||
#
|
||||
#plugins += [GoogleBooks, GoogleImages, Amazon, Edelweiss, OpenLibrary, OverDrive, Douban, Ozon, BigBookSearch]
|
||||
|
||||
# }}}
|
||||
|
||||
# Interface Actions {{{
|
||||
@@ -1098,823 +1083,6 @@ plugins += [ActionAdd, ActionFetchAnnotations, ActionGenerateCatalog,
|
||||
|
||||
# }}}
|
||||
|
||||
# Preferences Plugins {{{
|
||||
|
||||
|
||||
# class LookAndFeel(PreferencesPlugin):
|
||||
# name = 'Look & Feel'
|
||||
# icon = I('lookfeel.png')
|
||||
# gui_name = _('Look & feel')
|
||||
# category = 'Interface'
|
||||
# gui_category = _('Interface')
|
||||
# category_order = 1
|
||||
# name_order = 1
|
||||
# config_widget = 'ebook_converter.gui2.preferences.look_feel'
|
||||
# description = _('Adjust the look and feel of the calibre interface'
|
||||
# ' to suit your tastes')
|
||||
|
||||
|
||||
# class Behavior(PreferencesPlugin):
|
||||
# name = 'Behavior'
|
||||
# icon = I('config.png')
|
||||
# gui_name = _('Behavior')
|
||||
# category = 'Interface'
|
||||
# gui_category = _('Interface')
|
||||
# category_order = 1
|
||||
# name_order = 2
|
||||
# config_widget = 'ebook_converter.gui2.preferences.behavior'
|
||||
# description = _('Change the way calibre behaves')
|
||||
|
||||
|
||||
# class Columns(PreferencesPlugin):
|
||||
# name = 'Custom Columns'
|
||||
# icon = I('column.png')
|
||||
# gui_name = _('Add your own columns')
|
||||
# category = 'Interface'
|
||||
# gui_category = _('Interface')
|
||||
# category_order = 1
|
||||
# name_order = 3
|
||||
# config_widget = 'ebook_converter.gui2.preferences.columns'
|
||||
# description = _('Add/remove your own columns to the calibre book list')
|
||||
|
||||
|
||||
# class Toolbar(PreferencesPlugin):
|
||||
# name = 'Toolbar'
|
||||
# icon = I('wizard.png')
|
||||
# gui_name = _('Toolbars & menus')
|
||||
# category = 'Interface'
|
||||
# gui_category = _('Interface')
|
||||
# category_order = 1
|
||||
# name_order = 4
|
||||
# config_widget = 'ebook_converter.gui2.preferences.toolbar'
|
||||
# description = _('Customize the toolbars and context menus, changing which'
|
||||
# ' actions are available in each')
|
||||
|
||||
|
||||
# class Search(PreferencesPlugin):
|
||||
# name = 'Search'
|
||||
# icon = I('search.png')
|
||||
# gui_name = _('Searching')
|
||||
# category = 'Interface'
|
||||
# gui_category = _('Interface')
|
||||
# category_order = 1
|
||||
# name_order = 5
|
||||
# config_widget = 'ebook_converter.gui2.preferences.search'
|
||||
# description = _('Customize the way searching for books works in calibre')
|
||||
|
||||
|
||||
# class InputOptions(PreferencesPlugin):
|
||||
# name = 'Input Options'
|
||||
# icon = I('arrow-down.png')
|
||||
# gui_name = _('Input options')
|
||||
# category = 'Conversion'
|
||||
# gui_category = _('Conversion')
|
||||
# category_order = 2
|
||||
# name_order = 1
|
||||
# config_widget = 'ebook_converter.gui2.preferences.conversion:InputOptions'
|
||||
# description = _('Set conversion options specific to each input format')
|
||||
|
||||
# def create_widget(self, *args, **kwargs):
|
||||
# # The DOC Input plugin tries to override this
|
||||
# self.config_widget = 'ebook_converter.gui2.preferences.conversion:InputOptions'
|
||||
# return PreferencesPlugin.create_widget(self, *args, **kwargs)
|
||||
|
||||
|
||||
# class CommonOptions(PreferencesPlugin):
|
||||
# name = 'Common Options'
|
||||
# icon = I('convert.png')
|
||||
# gui_name = _('Common options')
|
||||
# category = 'Conversion'
|
||||
# gui_category = _('Conversion')
|
||||
# category_order = 2
|
||||
# name_order = 2
|
||||
# config_widget = 'ebook_converter.gui2.preferences.conversion:CommonOptions'
|
||||
# description = _('Set conversion options common to all formats')
|
||||
|
||||
|
||||
# class OutputOptions(PreferencesPlugin):
|
||||
# name = 'Output Options'
|
||||
# icon = I('arrow-up.png')
|
||||
# gui_name = _('Output options')
|
||||
# category = 'Conversion'
|
||||
# gui_category = _('Conversion')
|
||||
# category_order = 2
|
||||
# name_order = 3
|
||||
# config_widget = 'ebook_converter.gui2.preferences.conversion:OutputOptions'
|
||||
# description = _('Set conversion options specific to each output format')
|
||||
|
||||
|
||||
# class Adding(PreferencesPlugin):
|
||||
# name = 'Adding'
|
||||
# icon = I('add_book.png')
|
||||
# gui_name = _('Adding books')
|
||||
# category = 'Import/Export'
|
||||
# gui_category = _('Import/export')
|
||||
# category_order = 3
|
||||
# name_order = 1
|
||||
# config_widget = 'ebook_converter.gui2.preferences.adding'
|
||||
# description = _('Control how calibre reads metadata from files when '
|
||||
# 'adding books')
|
||||
|
||||
|
||||
# class Saving(PreferencesPlugin):
|
||||
# name = 'Saving'
|
||||
# icon = I('save.png')
|
||||
# gui_name = _('Saving books to disk')
|
||||
# category = 'Import/Export'
|
||||
# gui_category = _('Import/export')
|
||||
# category_order = 3
|
||||
# name_order = 2
|
||||
# config_widget = 'ebook_converter.gui2.preferences.saving'
|
||||
# description = _('Control how calibre exports files from its database '
|
||||
# 'to disk when using Save to disk')
|
||||
|
||||
|
||||
# class Sending(PreferencesPlugin):
|
||||
# name = 'Sending'
|
||||
# icon = I('sync.png')
|
||||
# gui_name = _('Sending books to devices')
|
||||
# category = 'Import/Export'
|
||||
# gui_category = _('Import/export')
|
||||
# category_order = 3
|
||||
# name_order = 3
|
||||
# config_widget = 'ebook_converter.gui2.preferences.sending'
|
||||
# description = _('Control how calibre transfers files to your '
|
||||
# 'e-book reader')
|
||||
|
||||
|
||||
# class Plugboard(PreferencesPlugin):
|
||||
# name = 'Plugboard'
|
||||
# icon = I('plugboard.png')
|
||||
# gui_name = _('Metadata plugboards')
|
||||
# category = 'Import/Export'
|
||||
# gui_category = _('Import/export')
|
||||
# category_order = 3
|
||||
# name_order = 4
|
||||
# config_widget = 'ebook_converter.gui2.preferences.plugboard'
|
||||
# description = _('Change metadata fields before saving/sending')
|
||||
|
||||
|
||||
# class TemplateFunctions(PreferencesPlugin):
|
||||
# name = 'TemplateFunctions'
|
||||
# icon = I('template_funcs.png')
|
||||
# gui_name = _('Template functions')
|
||||
# category = 'Advanced'
|
||||
# gui_category = _('Advanced')
|
||||
# category_order = 5
|
||||
# name_order = 5
|
||||
# config_widget = 'ebook_converter.gui2.preferences.template_functions'
|
||||
# description = _('Create your own template functions')
|
||||
|
||||
|
||||
# class Email(PreferencesPlugin):
|
||||
# name = 'Email'
|
||||
# icon = I('mail.png')
|
||||
# gui_name = _('Sharing books by email')
|
||||
# category = 'Sharing'
|
||||
# gui_category = _('Sharing')
|
||||
# category_order = 4
|
||||
# name_order = 1
|
||||
# config_widget = 'ebook_converter.gui2.preferences.emailp'
|
||||
# description = _('Setup sharing of books via email. Can be used '
|
||||
# 'for automatic sending of downloaded news to your devices')
|
||||
|
||||
|
||||
# class Server(PreferencesPlugin):
|
||||
# name = 'Server'
|
||||
# icon = I('network-server.png')
|
||||
# gui_name = _('Sharing over the net')
|
||||
# category = 'Sharing'
|
||||
# gui_category = _('Sharing')
|
||||
# category_order = 4
|
||||
# name_order = 2
|
||||
# config_widget = 'ebook_converter.gui2.preferences.server'
|
||||
# description = _('Setup the calibre Content server which will '
|
||||
# 'give you access to your calibre library from anywhere, '
|
||||
# 'on any device, over the internet')
|
||||
|
||||
|
||||
# class MetadataSources(PreferencesPlugin):
|
||||
# name = 'Metadata download'
|
||||
# icon = I('download-metadata.png')
|
||||
# gui_name = _('Metadata download')
|
||||
# category = 'Sharing'
|
||||
# gui_category = _('Sharing')
|
||||
# category_order = 4
|
||||
# name_order = 3
|
||||
# config_widget = 'ebook_converter.gui2.preferences.metadata_sources'
|
||||
# description = _('Control how calibre downloads e-book metadata from the net')
|
||||
|
||||
|
||||
# class IgnoredDevices(PreferencesPlugin):
|
||||
# name = 'Ignored Devices'
|
||||
# icon = I('reader.png')
|
||||
# gui_name = _('Ignored devices')
|
||||
# category = 'Sharing'
|
||||
# gui_category = _('Sharing')
|
||||
# category_order = 4
|
||||
# name_order = 4
|
||||
# config_widget = 'ebook_converter.gui2.preferences.ignored_devices'
|
||||
# description = _('Control which devices calibre will ignore when they are connected '
|
||||
# 'to the computer.')
|
||||
|
||||
|
||||
# class Plugins(PreferencesPlugin):
|
||||
# name = 'Plugins'
|
||||
# icon = I('plugins.png')
|
||||
# gui_name = _('Plugins')
|
||||
# category = 'Advanced'
|
||||
# gui_category = _('Advanced')
|
||||
# category_order = 5
|
||||
# name_order = 1
|
||||
# config_widget = 'ebook_converter.gui2.preferences.plugins'
|
||||
# description = _('Add/remove/customize various bits of calibre '
|
||||
# 'functionality')
|
||||
|
||||
|
||||
# class Tweaks(PreferencesPlugin):
|
||||
# name = 'Tweaks'
|
||||
# icon = I('tweaks.png')
|
||||
# gui_name = _('Tweaks')
|
||||
# category = 'Advanced'
|
||||
# gui_category = _('Advanced')
|
||||
# category_order = 5
|
||||
# name_order = 2
|
||||
# config_widget = 'ebook_converter.gui2.preferences.tweaks'
|
||||
# description = _('Fine tune how calibre behaves in various contexts')
|
||||
|
||||
|
||||
# class Keyboard(PreferencesPlugin):
|
||||
# name = 'Keyboard'
|
||||
# icon = I('keyboard-prefs.png')
|
||||
# gui_name = _('Shortcuts')
|
||||
# category = 'Advanced'
|
||||
# gui_category = _('Advanced')
|
||||
# category_order = 5
|
||||
# name_order = 4
|
||||
# config_widget = 'ebook_converter.gui2.preferences.keyboard'
|
||||
# description = _('Customize the keyboard shortcuts used by calibre')
|
||||
|
||||
|
||||
# class Misc(PreferencesPlugin):
|
||||
# name = 'Misc'
|
||||
# icon = I('exec.png')
|
||||
# gui_name = _('Miscellaneous')
|
||||
# category = 'Advanced'
|
||||
# gui_category = _('Advanced')
|
||||
# category_order = 5
|
||||
# name_order = 3
|
||||
# config_widget = 'ebook_converter.gui2.preferences.misc'
|
||||
# description = _('Miscellaneous advanced configuration')
|
||||
|
||||
|
||||
# plugins += [LookAndFeel, Behavior, Columns, Toolbar, Search, InputOptions,
|
||||
# CommonOptions, OutputOptions, Adding, Saving, Sending, Plugboard,
|
||||
# Email, Server, Plugins, Tweaks, Misc, TemplateFunctions,
|
||||
# MetadataSources, Keyboard, IgnoredDevices]
|
||||
|
||||
# }}}
|
||||
|
||||
# Store plugins {{{
|
||||
|
||||
|
||||
class StoreAmazonKindleStore(StoreBase):
|
||||
name = 'Amazon Kindle'
|
||||
description = 'Kindle books from Amazon.'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.amazon_plugin:AmazonKindleStore'
|
||||
|
||||
headquarters = 'US'
|
||||
formats = ['KINDLE']
|
||||
affiliate = False
|
||||
|
||||
|
||||
class StoreAmazonAUKindleStore(StoreBase):
|
||||
name = 'Amazon AU Kindle'
|
||||
author = 'Kovid Goyal'
|
||||
description = 'Kindle books from Amazon.'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.amazon_au_plugin:AmazonKindleStore'
|
||||
|
||||
headquarters = 'AU'
|
||||
formats = ['KINDLE']
|
||||
|
||||
|
||||
class StoreAmazonCAKindleStore(StoreBase):
|
||||
name = 'Amazon CA Kindle'
|
||||
author = 'Kovid Goyal'
|
||||
description = 'Kindle books from Amazon.'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.amazon_ca_plugin:AmazonKindleStore'
|
||||
|
||||
headquarters = 'CA'
|
||||
formats = ['KINDLE']
|
||||
|
||||
|
||||
class StoreAmazonINKindleStore(StoreBase):
|
||||
name = 'Amazon IN Kindle'
|
||||
author = 'Kovid Goyal'
|
||||
description = 'Kindle books from Amazon.'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.amazon_in_plugin:AmazonKindleStore'
|
||||
|
||||
headquarters = 'IN'
|
||||
formats = ['KINDLE']
|
||||
|
||||
|
||||
class StoreAmazonDEKindleStore(StoreBase):
|
||||
name = 'Amazon DE Kindle'
|
||||
author = 'Kovid Goyal'
|
||||
description = 'Kindle Bücher von Amazon.'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.amazon_de_plugin:AmazonKindleStore'
|
||||
|
||||
headquarters = 'DE'
|
||||
formats = ['KINDLE']
|
||||
|
||||
|
||||
class StoreAmazonFRKindleStore(StoreBase):
|
||||
name = 'Amazon FR Kindle'
|
||||
author = 'Kovid Goyal'
|
||||
description = 'Tous les e-books Kindle'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.amazon_fr_plugin:AmazonKindleStore'
|
||||
|
||||
headquarters = 'FR'
|
||||
formats = ['KINDLE']
|
||||
|
||||
|
||||
class StoreAmazonITKindleStore(StoreBase):
|
||||
name = 'Amazon IT Kindle'
|
||||
author = 'Kovid Goyal'
|
||||
description = 'e-book Kindle a prezzi incredibili'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.amazon_it_plugin:AmazonKindleStore'
|
||||
|
||||
headquarters = 'IT'
|
||||
formats = ['KINDLE']
|
||||
|
||||
|
||||
class StoreAmazonESKindleStore(StoreBase):
|
||||
name = 'Amazon ES Kindle'
|
||||
author = 'Kovid Goyal'
|
||||
description = 'e-book Kindle en España'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.amazon_es_plugin:AmazonKindleStore'
|
||||
|
||||
headquarters = 'ES'
|
||||
formats = ['KINDLE']
|
||||
|
||||
|
||||
class StoreAmazonUKKindleStore(StoreBase):
|
||||
name = 'Amazon UK Kindle'
|
||||
author = 'Kovid Goyal'
|
||||
description = 'Kindle books from Amazon\'s UK web site. Also, includes French language e-books.'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.amazon_uk_plugin:AmazonKindleStore'
|
||||
|
||||
headquarters = 'UK'
|
||||
formats = ['KINDLE']
|
||||
|
||||
|
||||
class StoreArchiveOrgStore(StoreBase):
|
||||
name = 'Archive.org'
|
||||
description = 'An Internet library offering permanent access for researchers, historians, scholars, people with disabilities, and the general public to historical collections that exist in digital format.' # noqa
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.archive_org_plugin:ArchiveOrgStore'
|
||||
|
||||
drm_free_only = True
|
||||
headquarters = 'US'
|
||||
formats = ['DAISY', 'DJVU', 'EPUB', 'MOBI', 'PDF', 'TXT']
|
||||
|
||||
|
||||
class StoreBubokPublishingStore(StoreBase):
|
||||
name = 'Bubok Spain'
|
||||
description = 'Bubok Publishing is a publisher, library and store of books of authors from all around the world. They have a big amount of books of a lot of topics' # noqa
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.bubok_publishing_plugin:BubokPublishingStore'
|
||||
|
||||
drm_free_only = True
|
||||
headquarters = 'ES'
|
||||
formats = ['EPUB', 'PDF']
|
||||
|
||||
|
||||
class StoreBubokPortugalStore(StoreBase):
|
||||
name = 'Bubok Portugal'
|
||||
description = 'Bubok Publishing Portugal is a publisher, library and store of books of authors from Portugal. They have a big amount of books of a lot of topics' # noqa
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.bubok_portugal_plugin:BubokPortugalStore'
|
||||
|
||||
drm_free_only = True
|
||||
headquarters = 'PT'
|
||||
formats = ['EPUB', 'PDF']
|
||||
|
||||
|
||||
class StoreBaenWebScriptionStore(StoreBase):
|
||||
name = 'Baen Ebooks'
|
||||
description = 'Sci-Fi & Fantasy brought to you by Jim Baen.'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.baen_webscription_plugin:BaenWebScriptionStore'
|
||||
|
||||
drm_free_only = True
|
||||
headquarters = 'US'
|
||||
formats = ['EPUB', 'LIT', 'LRF', 'MOBI', 'RB', 'RTF', 'ZIP']
|
||||
|
||||
|
||||
class StoreBNStore(StoreBase):
|
||||
name = 'Barnes and Noble'
|
||||
description = 'The world\'s largest book seller. As the ultimate destination for book lovers, Barnes & Noble.com offers an incredible array of content.'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.bn_plugin:BNStore'
|
||||
|
||||
headquarters = 'US'
|
||||
formats = ['NOOK']
|
||||
|
||||
|
||||
class StoreBeamEBooksDEStore(StoreBase):
|
||||
name = 'Beam EBooks DE'
|
||||
author = 'Charles Haley'
|
||||
description = 'Bei uns finden Sie: Tausende deutschsprachige e-books; Alle e-books ohne hartes DRM; PDF, ePub und Mobipocket Format; Sofortige Verfügbarkeit - 24 Stunden am Tag; Günstige Preise; e-books für viele Lesegeräte, PC,Mac und Smartphones; Viele Gratis e-books' # noqa
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.beam_ebooks_de_plugin:BeamEBooksDEStore'
|
||||
|
||||
drm_free_only = True
|
||||
headquarters = 'DE'
|
||||
formats = ['EPUB', 'MOBI', 'PDF']
|
||||
|
||||
|
||||
class StoreBiblioStore(StoreBase):
|
||||
name = 'Библио.бг'
|
||||
author = 'Alex Stanev'
|
||||
description = 'Електронна книжарница за книги и списания във формати ePUB и PDF. Част от заглавията са с активна DRM защита.'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.biblio_plugin:BiblioStore'
|
||||
|
||||
headquarters = 'BG'
|
||||
formats = ['EPUB, PDF']
|
||||
|
||||
|
||||
class StoreChitankaStore(StoreBase):
|
||||
name = 'Моята библиотека'
|
||||
author = 'Alex Stanev'
|
||||
description = 'Независим сайт за DRM свободна литература на български език'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.chitanka_plugin:ChitankaStore'
|
||||
|
||||
drm_free_only = True
|
||||
headquarters = 'BG'
|
||||
formats = ['FB2', 'EPUB', 'TXT', 'SFB']
|
||||
|
||||
|
||||
class StoreEbookNLStore(StoreBase):
|
||||
name = 'eBook.nl'
|
||||
description = 'De eBookwinkel van Nederland'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.ebook_nl_plugin:EBookNLStore'
|
||||
|
||||
headquarters = 'NL'
|
||||
formats = ['EPUB', 'PDF']
|
||||
affiliate = False
|
||||
|
||||
|
||||
class StoreEbookpointStore(StoreBase):
|
||||
name = 'Ebookpoint'
|
||||
author = 'Tomasz Długosz'
|
||||
description = 'E-booki wolne od DRM, 3 formaty w pakiecie, wysyłanie na Kindle'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.ebookpoint_plugin:EbookpointStore'
|
||||
|
||||
drm_free_only = True
|
||||
headquarters = 'PL'
|
||||
formats = ['EPUB', 'MOBI', 'PDF']
|
||||
affiliate = True
|
||||
|
||||
|
||||
class StoreEbookscomStore(StoreBase):
|
||||
name = 'eBooks.com'
|
||||
description = 'Sells books in multiple electronic formats in all categories. Technical infrastructure is cutting edge, robust and scalable, with servers in the US and Europe.' # noqa
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.ebooks_com_plugin:EbookscomStore'
|
||||
|
||||
headquarters = 'US'
|
||||
formats = ['EPUB', 'LIT', 'MOBI', 'PDF']
|
||||
affiliate = True
|
||||
|
||||
|
||||
class StoreEbooksGratuitsStore(StoreBase):
|
||||
name = 'EbooksGratuits.com'
|
||||
description = 'Ebooks Libres et Gratuits'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.ebooksgratuits_plugin:EbooksGratuitsStore'
|
||||
|
||||
headquarters = 'FR'
|
||||
formats = ['EPUB', 'MOBI', 'PDF', 'PDB']
|
||||
drm_free_only = True
|
||||
|
||||
# class StoreEBookShoppeUKStore(StoreBase):
|
||||
# name = 'ebookShoppe UK'
|
||||
# author = 'Charles Haley'
|
||||
# description = 'We made this website in an attempt to offer the widest range of UK eBooks possible across and as many formats as we could manage.'
|
||||
# actual_plugin = 'ebook_converter.gui2.store.stores.ebookshoppe_uk_plugin:EBookShoppeUKStore'
|
||||
#
|
||||
# headquarters = 'UK'
|
||||
# formats = ['EPUB', 'PDF']
|
||||
# affiliate = True
|
||||
|
||||
|
||||
class StoreEKnigiStore(StoreBase):
|
||||
name = 'еКниги'
|
||||
author = 'Alex Stanev'
|
||||
description = 'Онлайн книжарница за електронни книги и аудио риалити романи'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.eknigi_plugin:eKnigiStore'
|
||||
|
||||
headquarters = 'BG'
|
||||
formats = ['EPUB', 'PDF', 'HTML']
|
||||
affiliate = True
|
||||
|
||||
|
||||
class StoreEmpikStore(StoreBase):
|
||||
name = 'Empik'
|
||||
author = 'Tomasz Długosz'
|
||||
description = 'Empik to marka o unikalnym dziedzictwie i legendarne miejsce, dawne “okno na świat”. Jest obecna w polskim krajobrazie kulturalnym od 60 lat (wcześniej jako Kluby Międzynarodowej Prasy i Książki).' # noqa
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.empik_plugin:EmpikStore'
|
||||
|
||||
headquarters = 'PL'
|
||||
formats = ['EPUB', 'MOBI', 'PDF']
|
||||
affiliate = True
|
||||
|
||||
|
||||
class StoreFeedbooksStore(StoreBase):
|
||||
name = 'Feedbooks'
|
||||
description = 'Feedbooks is a cloud publishing and distribution service, connected to a large ecosystem of reading systems and social networks. Provides a variety of genres from independent and classic books.' # noqa
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.feedbooks_plugin:FeedbooksStore'
|
||||
|
||||
headquarters = 'FR'
|
||||
formats = ['EPUB', 'MOBI', 'PDF']
|
||||
|
||||
|
||||
class StoreGoogleBooksStore(StoreBase):
|
||||
name = 'Google Books'
|
||||
description = 'Google Books'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.google_books_plugin:GoogleBooksStore'
|
||||
|
||||
headquarters = 'US'
|
||||
formats = ['EPUB', 'PDF', 'TXT']
|
||||
|
||||
|
||||
class StoreGutenbergStore(StoreBase):
|
||||
name = 'Project Gutenberg'
|
||||
description = 'The first producer of free e-books. Free in the United States because their copyright has expired. They may not be free of copyright in other countries. Readers outside of the United States must check the copyright laws of their countries before downloading or redistributing our e-books.' # noqa
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.gutenberg_plugin:GutenbergStore'
|
||||
|
||||
drm_free_only = True
|
||||
headquarters = 'US'
|
||||
formats = ['EPUB', 'HTML', 'MOBI', 'PDB', 'TXT']
|
||||
|
||||
|
||||
class StoreKoboStore(StoreBase):
|
||||
name = 'Kobo'
|
||||
description = 'With over 2.3 million e-books to browse we have engaged readers in over 200 countries in Kobo eReading. Our e-book listings include New York Times Bestsellers, award winners, classics and more!' # noqa
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.kobo_plugin:KoboStore'
|
||||
|
||||
headquarters = 'CA'
|
||||
formats = ['EPUB']
|
||||
affiliate = True
|
||||
|
||||
|
||||
class StoreLegimiStore(StoreBase):
|
||||
name = 'Legimi'
|
||||
author = 'Tomasz Długosz'
|
||||
description = 'E-booki w formacie EPUB, MOBI i PDF'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.legimi_plugin:LegimiStore'
|
||||
|
||||
headquarters = 'PL'
|
||||
formats = ['EPUB', 'PDF', 'MOBI']
|
||||
affiliate = True
|
||||
|
||||
|
||||
class StoreLibreDEStore(StoreBase):
|
||||
name = 'ebook.de'
|
||||
author = 'Charles Haley'
|
||||
description = 'All Ihre Bücher immer dabei. Suchen, finden, kaufen: so einfach wie nie. ebook.de war libre.de'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.libri_de_plugin:LibreDEStore'
|
||||
|
||||
headquarters = 'DE'
|
||||
formats = ['EPUB', 'PDF']
|
||||
affiliate = True
|
||||
|
||||
|
||||
class StoreLitResStore(StoreBase):
|
||||
name = 'LitRes'
|
||||
description = 'e-books from LitRes.ru'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.litres_plugin:LitResStore'
|
||||
author = 'Roman Mukhin'
|
||||
|
||||
drm_free_only = False
|
||||
headquarters = 'RU'
|
||||
formats = ['EPUB', 'TXT', 'RTF', 'HTML', 'FB2', 'LRF', 'PDF', 'MOBI', 'LIT', 'ISILO3', 'JAR', 'RB', 'PRC']
|
||||
affiliate = True
|
||||
|
||||
|
||||
class StoreManyBooksStore(StoreBase):
|
||||
name = 'ManyBooks'
|
||||
description = 'Public domain and creative commons works from many sources.'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.manybooks_plugin:ManyBooksStore'
|
||||
|
||||
drm_free_only = True
|
||||
headquarters = 'US'
|
||||
formats = ['EPUB', 'FB2', 'JAR', 'LIT', 'LRF', 'MOBI', 'PDB', 'PDF', 'RB', 'RTF', 'TCR', 'TXT', 'ZIP']
|
||||
|
||||
|
||||
class StoreMillsBoonUKStore(StoreBase):
|
||||
name = 'Mills and Boon UK'
|
||||
author = 'Charles Haley'
|
||||
description = '"Bring Romance to Life" "[A] hallmark for romantic fiction, recognised around the world."'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.mills_boon_uk_plugin:MillsBoonUKStore'
|
||||
|
||||
headquarters = 'UK'
|
||||
formats = ['EPUB']
|
||||
affiliate = False
|
||||
|
||||
|
||||
class StoreMobileReadStore(StoreBase):
|
||||
name = 'MobileRead'
|
||||
description = 'E-books handcrafted with the utmost care.'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.mobileread.mobileread_plugin:MobileReadStore'
|
||||
|
||||
drm_free_only = True
|
||||
headquarters = 'CH'
|
||||
formats = ['EPUB', 'IMP', 'LRF', 'LIT', 'MOBI', 'PDF']
|
||||
|
||||
|
||||
class StoreNextoStore(StoreBase):
|
||||
name = 'Nexto'
|
||||
author = 'Tomasz Długosz'
|
||||
description = 'Największy w Polsce sklep internetowy z audiobookami mp3, ebookami pdf oraz prasą do pobrania on-line.'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.nexto_plugin:NextoStore'
|
||||
|
||||
headquarters = 'PL'
|
||||
formats = ['EPUB', 'MOBI', 'PDF']
|
||||
affiliate = True
|
||||
|
||||
|
||||
class StoreOzonRUStore(StoreBase):
|
||||
name = 'OZON.ru'
|
||||
description = 'e-books from OZON.ru'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.ozon_ru_plugin:OzonRUStore'
|
||||
author = 'Roman Mukhin'
|
||||
|
||||
drm_free_only = True
|
||||
headquarters = 'RU'
|
||||
formats = ['TXT', 'PDF', 'DJVU', 'RTF', 'DOC', 'JAR', 'FB2']
|
||||
affiliate = True
|
||||
|
||||
|
||||
class StorePragmaticBookshelfStore(StoreBase):
|
||||
name = 'Pragmatic Bookshelf'
|
||||
description = 'The Pragmatic Bookshelf\'s collection of programming and tech books avaliable as e-books.'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.pragmatic_bookshelf_plugin:PragmaticBookshelfStore'
|
||||
|
||||
drm_free_only = True
|
||||
headquarters = 'US'
|
||||
formats = ['EPUB', 'MOBI', 'PDF']
|
||||
|
||||
|
||||
class StorePublioStore(StoreBase):
|
||||
name = 'Publio'
|
||||
description = 'Publio.pl to księgarnia internetowa, w której mogą Państwo nabyć e-booki i audiobooki.'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.publio_plugin:PublioStore'
|
||||
author = 'Tomasz Długosz'
|
||||
|
||||
headquarters = 'PL'
|
||||
formats = ['EPUB', 'MOBI', 'PDF']
|
||||
affiliate = True
|
||||
|
||||
|
||||
class StoreRW2010Store(StoreBase):
|
||||
name = 'RW2010'
|
||||
description = 'Polski serwis self-publishingowy. Pliki PDF, EPUB i MOBI.'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.rw2010_plugin:RW2010Store'
|
||||
author = 'Tomasz Długosz'
|
||||
|
||||
drm_free_only = True
|
||||
headquarters = 'PL'
|
||||
formats = ['EPUB', 'MOBI', 'PDF']
|
||||
|
||||
|
||||
class StoreSmashwordsStore(StoreBase):
|
||||
name = 'Smashwords'
|
||||
description = 'An e-book publishing and distribution platform for e-book authors, publishers and readers. Covers many genres and formats.'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.smashwords_plugin:SmashwordsStore'
|
||||
|
||||
drm_free_only = True
|
||||
headquarters = 'US'
|
||||
formats = ['EPUB', 'HTML', 'LRF', 'MOBI', 'PDB', 'RTF', 'TXT']
|
||||
affiliate = True
|
||||
|
||||
|
||||
class StoreSwiatEbookowStore(StoreBase):
|
||||
name = 'Świat Ebooków'
|
||||
author = 'Tomasz Długosz'
|
||||
description = 'Ebooki maje tę zaletę, że są zawsze i wszędzie tam, gdzie tylko nas dopadnie ochota na czytanie.'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.swiatebookow_plugin:SwiatEbookowStore'
|
||||
|
||||
drm_free_only = True
|
||||
headquarters = 'PL'
|
||||
formats = ['EPUB', 'MOBI', 'PDF']
|
||||
affiliate = True
|
||||
|
||||
|
||||
class StoreVirtualoStore(StoreBase):
|
||||
name = 'Virtualo'
|
||||
author = 'Tomasz Długosz'
|
||||
description = 'Księgarnia internetowa, która oferuje bezpieczny i szeroki dostęp do książek w formie cyfrowej.'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.virtualo_plugin:VirtualoStore'
|
||||
|
||||
headquarters = 'PL'
|
||||
formats = ['EPUB', 'MOBI', 'PDF']
|
||||
affiliate = True
|
||||
|
||||
|
||||
class StoreWeightlessBooksStore(StoreBase):
|
||||
name = 'Weightless Books'
|
||||
description = 'An independent DRM-free e-book site devoted to e-books of all sorts.'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.weightless_books_plugin:WeightlessBooksStore'
|
||||
|
||||
drm_free_only = True
|
||||
headquarters = 'US'
|
||||
formats = ['EPUB', 'HTML', 'LIT', 'MOBI', 'PDF']
|
||||
|
||||
|
||||
class StoreWHSmithUKStore(StoreBase):
|
||||
name = 'WH Smith UK'
|
||||
author = 'Charles Haley'
|
||||
description = u"Shop for savings on Books, discounted Magazine subscriptions and great prices on Stationery, Toys & Games"
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.whsmith_uk_plugin:WHSmithUKStore'
|
||||
|
||||
headquarters = 'UK'
|
||||
formats = ['EPUB', 'PDF']
|
||||
|
||||
|
||||
class StoreWolneLekturyStore(StoreBase):
|
||||
name = 'Wolne Lektury'
|
||||
author = 'Tomasz Długosz'
|
||||
description = 'Wolne Lektury to biblioteka internetowa czynna 24 godziny na dobę, 365 dni w roku, której zasoby dostępne są całkowicie za darmo. Wszystkie dzieła są odpowiednio opracowane - opatrzone przypisami, motywami i udostępnione w kilku formatach - HTML, TXT, PDF, EPUB, MOBI, FB2.' # noqa
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.wolnelektury_plugin:WolneLekturyStore'
|
||||
|
||||
headquarters = 'PL'
|
||||
formats = ['EPUB', 'MOBI', 'PDF', 'TXT', 'FB2']
|
||||
|
||||
|
||||
class StoreWoblinkStore(StoreBase):
|
||||
name = 'Woblink'
|
||||
author = 'Tomasz Długosz'
|
||||
description = 'Czytanie zdarza się wszędzie!'
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.woblink_plugin:WoblinkStore'
|
||||
|
||||
headquarters = 'PL'
|
||||
formats = ['EPUB', 'MOBI', 'PDF', 'WOBLINK']
|
||||
affiliate = True
|
||||
|
||||
|
||||
class XinXiiStore(StoreBase):
|
||||
name = 'XinXii'
|
||||
description = ''
|
||||
actual_plugin = 'ebook_converter.gui2.store.stores.xinxii_plugin:XinXiiStore'
|
||||
|
||||
headquarters = 'DE'
|
||||
formats = ['EPUB', 'PDF']
|
||||
|
||||
|
||||
plugins += [
|
||||
StoreArchiveOrgStore,
|
||||
StoreBubokPublishingStore,
|
||||
StoreBubokPortugalStore,
|
||||
StoreAmazonKindleStore,
|
||||
StoreAmazonAUKindleStore,
|
||||
StoreAmazonCAKindleStore,
|
||||
StoreAmazonINKindleStore,
|
||||
StoreAmazonDEKindleStore,
|
||||
StoreAmazonESKindleStore,
|
||||
StoreAmazonFRKindleStore,
|
||||
StoreAmazonITKindleStore,
|
||||
StoreAmazonUKKindleStore,
|
||||
StoreBaenWebScriptionStore,
|
||||
StoreBNStore,
|
||||
StoreBeamEBooksDEStore,
|
||||
StoreBiblioStore,
|
||||
StoreChitankaStore,
|
||||
StoreEbookNLStore,
|
||||
StoreEbookpointStore,
|
||||
StoreEbookscomStore,
|
||||
StoreEbooksGratuitsStore,
|
||||
StoreEKnigiStore,
|
||||
StoreEmpikStore,
|
||||
StoreFeedbooksStore,
|
||||
StoreGoogleBooksStore,
|
||||
StoreGutenbergStore,
|
||||
StoreKoboStore,
|
||||
StoreLegimiStore,
|
||||
StoreLibreDEStore,
|
||||
StoreLitResStore,
|
||||
StoreManyBooksStore,
|
||||
StoreMillsBoonUKStore,
|
||||
StoreMobileReadStore,
|
||||
StoreNextoStore,
|
||||
StoreOzonRUStore,
|
||||
StorePragmaticBookshelfStore,
|
||||
StorePublioStore,
|
||||
StoreRW2010Store,
|
||||
StoreSmashwordsStore,
|
||||
StoreSwiatEbookowStore,
|
||||
StoreVirtualoStore,
|
||||
StoreWeightlessBooksStore,
|
||||
StoreWHSmithUKStore,
|
||||
StoreWolneLekturyStore,
|
||||
StoreWoblinkStore,
|
||||
XinXiiStore
|
||||
]
|
||||
|
||||
# }}}
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Test load speed
|
||||
|
||||
@@ -1,28 +1,21 @@
|
||||
import os, shutil, traceback, functools, sys
|
||||
from collections import defaultdict
|
||||
from itertools import chain
|
||||
import collections
|
||||
import functools
|
||||
import itertools
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
from ebook_converter.customize import (CatalogPlugin, FileTypePlugin, PluginNotFound,
|
||||
MetadataReaderPlugin, MetadataWriterPlugin,
|
||||
InterfaceActionBase as InterfaceAction,
|
||||
PreferencesPlugin, platform, InvalidPlugin,
|
||||
StoreBase as Store, EditBookToolPlugin,
|
||||
LibraryClosedPlugin)
|
||||
from ebook_converter.customize.conversion import InputFormatPlugin, OutputFormatPlugin
|
||||
from ebook_converter.customize.profiles import InputProfile, OutputProfile
|
||||
from ebook_converter.customize.builtins import plugins as builtin_plugins
|
||||
# from ebook_converter.devices.interface import DevicePlugin
|
||||
from ebook_converter.ebooks.metadata import MetaInformation
|
||||
from ebook_converter.utils.config import (make_config_dir, Config, ConfigProxy,
|
||||
plugin_dir, OptionParser)
|
||||
# from ebook_converter.ebooks.metadata.sources.base import Source
|
||||
from ebook_converter.constants import DEBUG, numeric_version
|
||||
from ebook_converter import customize
|
||||
from ebook_converter.customize import conversion
|
||||
from ebook_converter.customize import profiles
|
||||
from ebook_converter.customize import builtins
|
||||
from ebook_converter.ebooks import metadata
|
||||
from ebook_converter.utils import config as cfg
|
||||
from ebook_converter import constants
|
||||
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
|
||||
builtin_names = frozenset(p.name for p in builtin_plugins)
|
||||
builtin_names = frozenset(p.name for p in builtins.plugins)
|
||||
BLACKLISTED_PLUGINS = frozenset({'Marvin XD', 'iOS reader applications'})
|
||||
|
||||
|
||||
@@ -31,107 +24,40 @@ class NameConflict(ValueError):
|
||||
|
||||
|
||||
def _config():
|
||||
c = Config('customize')
|
||||
c = cfg.Config('customize')
|
||||
c.add_opt('plugins', default={}, help=_('Installed plugins'))
|
||||
c.add_opt('filetype_mapping', default={}, help=_('Mapping for filetype plugins'))
|
||||
c.add_opt('plugin_customization', default={}, help=_('Local plugin customization'))
|
||||
c.add_opt('filetype_mapping', default={},
|
||||
help=_('Mapping for filetype plugins'))
|
||||
c.add_opt('plugin_customization', default={},
|
||||
help=_('Local plugin customization'))
|
||||
c.add_opt('disabled_plugins', default=set(), help=_('Disabled plugins'))
|
||||
c.add_opt('enabled_plugins', default=set(), help=_('Enabled plugins'))
|
||||
|
||||
return ConfigProxy(c)
|
||||
return cfg.ConfigProxy(c)
|
||||
|
||||
|
||||
config = _config()
|
||||
|
||||
|
||||
def find_plugin(name):
|
||||
for plugin in _initialized_plugins:
|
||||
if plugin.name == name:
|
||||
return plugin
|
||||
|
||||
|
||||
def load_plugin(path_to_zip_file): # {{{
|
||||
'''
|
||||
Load plugin from ZIP file or raise InvalidPlugin error
|
||||
|
||||
:return: A :class:`Plugin` instance.
|
||||
'''
|
||||
return loader.load(path_to_zip_file)
|
||||
|
||||
# }}}
|
||||
|
||||
# Enable/disable plugins {{{
|
||||
|
||||
|
||||
def disable_plugin(plugin_or_name):
|
||||
x = getattr(plugin_or_name, 'name', plugin_or_name)
|
||||
plugin = find_plugin(x)
|
||||
if not plugin.can_be_disabled:
|
||||
raise ValueError('Plugin %s cannot be disabled'%x)
|
||||
dp = config['disabled_plugins']
|
||||
dp.add(x)
|
||||
config['disabled_plugins'] = dp
|
||||
ep = config['enabled_plugins']
|
||||
if x in ep:
|
||||
ep.remove(x)
|
||||
config['enabled_plugins'] = ep
|
||||
|
||||
|
||||
def enable_plugin(plugin_or_name):
|
||||
x = getattr(plugin_or_name, 'name', plugin_or_name)
|
||||
dp = config['disabled_plugins']
|
||||
if x in dp:
|
||||
dp.remove(x)
|
||||
config['disabled_plugins'] = dp
|
||||
ep = config['enabled_plugins']
|
||||
ep.add(x)
|
||||
config['enabled_plugins'] = ep
|
||||
|
||||
|
||||
def restore_plugin_state_to_default(plugin_or_name):
|
||||
x = getattr(plugin_or_name, 'name', plugin_or_name)
|
||||
dp = config['disabled_plugins']
|
||||
if x in dp:
|
||||
dp.remove(x)
|
||||
config['disabled_plugins'] = dp
|
||||
ep = config['enabled_plugins']
|
||||
if x in ep:
|
||||
ep.remove(x)
|
||||
config['enabled_plugins'] = ep
|
||||
|
||||
|
||||
default_disabled_plugins = {
|
||||
'Overdrive', 'Douban Books', 'OZON.ru', 'Edelweiss', 'Google Images', 'Big Book Search',
|
||||
}
|
||||
|
||||
|
||||
def is_disabled(plugin):
|
||||
if plugin.name in config['enabled_plugins']:
|
||||
return False
|
||||
return plugin.name in config['disabled_plugins'] or \
|
||||
plugin.name in default_disabled_plugins
|
||||
# }}}
|
||||
|
||||
# File type plugins {{{
|
||||
|
||||
|
||||
_on_import = {}
|
||||
_on_postimport = {}
|
||||
_on_preprocess = {}
|
||||
_on_postprocess = {}
|
||||
_on_postadd = []
|
||||
# File type plugins
|
||||
_on_import = {}
|
||||
_on_postimport = {}
|
||||
_on_preprocess = {}
|
||||
_on_postprocess = {}
|
||||
_on_postadd = []
|
||||
|
||||
|
||||
def reread_filetype_plugins():
|
||||
global _on_import, _on_postimport, _on_preprocess, _on_postprocess, _on_postadd
|
||||
_on_import = defaultdict(list)
|
||||
_on_postimport = defaultdict(list)
|
||||
_on_preprocess = defaultdict(list)
|
||||
_on_postprocess = defaultdict(list)
|
||||
_on_postadd = []
|
||||
global _on_import, _on_postimport, _on_preprocess, _on_postprocess
|
||||
global _on_postadd
|
||||
_on_import = collections.defaultdict(list)
|
||||
_on_postimport = collections.defaultdict(list)
|
||||
_on_preprocess = collections.defaultdict(list)
|
||||
_on_postprocess = collections.defaultdict(list)
|
||||
_on_postadd = []
|
||||
|
||||
for plugin in _initialized_plugins:
|
||||
if isinstance(plugin, FileTypePlugin):
|
||||
if isinstance(plugin, customize.FileTypePlugin):
|
||||
for ft in plugin.file_types:
|
||||
if plugin.on_import:
|
||||
_on_import[ft].append(plugin)
|
||||
@@ -145,12 +71,12 @@ def reread_filetype_plugins():
|
||||
|
||||
|
||||
def plugins_for_ft(ft, occasion):
|
||||
op = {
|
||||
'import':_on_import, 'preprocess':_on_preprocess, 'postprocess':_on_postprocess, 'postimport':_on_postimport,
|
||||
}[occasion]
|
||||
for p in chain(op.get(ft, ()), op.get('*', ())):
|
||||
if not is_disabled(p):
|
||||
yield p
|
||||
op = {'import': _on_import,
|
||||
'preprocess': _on_preprocess,
|
||||
'postprocess': _on_postprocess,
|
||||
'postimport': _on_postimport}[occasion]
|
||||
for p in itertools.chain(op.get(ft, ()), op.get('*', ())):
|
||||
yield p
|
||||
|
||||
|
||||
def _run_filetype_plugins(path_to_file, ft=None, occasion='preprocess'):
|
||||
@@ -160,7 +86,9 @@ def _run_filetype_plugins(path_to_file, ft=None, occasion='preprocess'):
|
||||
nfp = path_to_file
|
||||
for plugin in plugins_for_ft(ft, occasion):
|
||||
plugin.site_customization = customization.get(plugin.name, '')
|
||||
oo, oe = sys.stdout, sys.stderr # Some file type plugins out there override the output streams with buggy implementations
|
||||
# Some file type plugins out there override the output streams with
|
||||
# buggy implementations
|
||||
oo, oe = sys.stdout, sys.stderr
|
||||
with plugin:
|
||||
try:
|
||||
plugin.original_path_to_file = path_to_file
|
||||
@@ -169,7 +97,8 @@ def _run_filetype_plugins(path_to_file, ft=None, occasion='preprocess'):
|
||||
try:
|
||||
nfp = plugin.run(nfp) or nfp
|
||||
except:
|
||||
print('Running file type plugin %s failed with traceback:'%plugin.name, file=oe)
|
||||
print('Running file type plugin %s failed with traceback:' %
|
||||
plugin.name, file=oe)
|
||||
traceback.print_exc(file=oe)
|
||||
sys.stdout, sys.stderr = oo, oe
|
||||
x = lambda j: os.path.normpath(os.path.normcase(j))
|
||||
@@ -179,9 +108,12 @@ def _run_filetype_plugins(path_to_file, ft=None, occasion='preprocess'):
|
||||
return nfp
|
||||
|
||||
|
||||
run_plugins_on_import = functools.partial(_run_filetype_plugins, occasion='import')
|
||||
run_plugins_on_preprocess = functools.partial(_run_filetype_plugins, occasion='preprocess')
|
||||
run_plugins_on_postprocess = functools.partial(_run_filetype_plugins, occasion='postprocess')
|
||||
run_plugins_on_import = functools.partial(_run_filetype_plugins,
|
||||
occasion='import')
|
||||
run_plugins_on_preprocess = functools.partial(_run_filetype_plugins,
|
||||
occasion='preprocess')
|
||||
run_plugins_on_postprocess = functools.partial(_run_filetype_plugins,
|
||||
occasion='postprocess')
|
||||
|
||||
|
||||
def run_plugins_on_postimport(db, book_id, fmt):
|
||||
@@ -192,31 +124,26 @@ def run_plugins_on_postimport(db, book_id, fmt):
|
||||
with plugin:
|
||||
try:
|
||||
plugin.postimport(book_id, fmt, db)
|
||||
except:
|
||||
print('Running file type plugin %s failed with traceback:'%
|
||||
plugin.name)
|
||||
except Exception:
|
||||
print('Running file type plugin %s failed with traceback:' %
|
||||
plugin.name)
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
def run_plugins_on_postadd(db, book_id, fmt_map):
|
||||
customization = config['plugin_customization']
|
||||
for plugin in _on_postadd:
|
||||
if is_disabled(plugin):
|
||||
continue
|
||||
plugin.site_customization = customization.get(plugin.name, '')
|
||||
with plugin:
|
||||
try:
|
||||
plugin.postadd(book_id, fmt_map, db)
|
||||
except Exception:
|
||||
print('Running file type plugin %s failed with traceback:'%
|
||||
plugin.name)
|
||||
print('Running file type plugin %s failed with traceback:' %
|
||||
plugin.name)
|
||||
traceback.print_exc()
|
||||
|
||||
# }}}
|
||||
|
||||
# Plugin customization {{{
|
||||
|
||||
|
||||
# Plugin customization
|
||||
def customize_plugin(plugin, custom):
|
||||
d = config['plugin_customization']
|
||||
d[plugin.name] = custom.strip()
|
||||
@@ -226,82 +153,64 @@ def customize_plugin(plugin, custom):
|
||||
def plugin_customization(plugin):
|
||||
return config['plugin_customization'].get(plugin.name, '')
|
||||
|
||||
# }}}
|
||||
|
||||
# Input/Output profiles {{{
|
||||
|
||||
|
||||
# Input/Output profiles
|
||||
def input_profiles():
|
||||
for plugin in _initialized_plugins:
|
||||
if isinstance(plugin, InputProfile):
|
||||
if isinstance(plugin, profiles.InputProfile):
|
||||
yield plugin
|
||||
|
||||
|
||||
def output_profiles():
|
||||
for plugin in _initialized_plugins:
|
||||
if isinstance(plugin, OutputProfile):
|
||||
if isinstance(plugin, profiles.OutputProfile):
|
||||
yield plugin
|
||||
# }}}
|
||||
|
||||
# Interface Actions # {{{
|
||||
|
||||
|
||||
# Interface Actions #
|
||||
def interface_actions():
|
||||
customization = config['plugin_customization']
|
||||
for plugin in _initialized_plugins:
|
||||
if isinstance(plugin, InterfaceAction):
|
||||
if not is_disabled(plugin):
|
||||
plugin.site_customization = customization.get(plugin.name, '')
|
||||
yield plugin
|
||||
# }}}
|
||||
|
||||
# Preferences Plugins # {{{
|
||||
if isinstance(plugin, customize.InterfaceActionBase):
|
||||
yield plugin
|
||||
|
||||
|
||||
# Preferences Plugins
|
||||
def preferences_plugins():
|
||||
customization = config['plugin_customization']
|
||||
for plugin in _initialized_plugins:
|
||||
if isinstance(plugin, PreferencesPlugin):
|
||||
if not is_disabled(plugin):
|
||||
plugin.site_customization = customization.get(plugin.name, '')
|
||||
yield plugin
|
||||
# }}}
|
||||
|
||||
# Library Closed Plugins # {{{
|
||||
if isinstance(plugin, customize.PreferencesPlugin):
|
||||
plugin.site_customization = customization.get(plugin.name, '')
|
||||
yield plugin
|
||||
|
||||
|
||||
# Library Closed Plugins
|
||||
def available_library_closed_plugins():
|
||||
customization = config['plugin_customization']
|
||||
for plugin in _initialized_plugins:
|
||||
if isinstance(plugin, LibraryClosedPlugin):
|
||||
if not is_disabled(plugin):
|
||||
plugin.site_customization = customization.get(plugin.name, '')
|
||||
yield plugin
|
||||
if isinstance(plugin, customize.LibraryClosedPlugin):
|
||||
plugin.site_customization = customization.get(plugin.name, '')
|
||||
yield plugin
|
||||
|
||||
|
||||
def has_library_closed_plugins():
|
||||
for plugin in _initialized_plugins:
|
||||
if isinstance(plugin, LibraryClosedPlugin):
|
||||
if not is_disabled(plugin):
|
||||
return True
|
||||
if isinstance(plugin, customize.LibraryClosedPlugin):
|
||||
return True
|
||||
return False
|
||||
# }}}
|
||||
|
||||
# Store Plugins # {{{
|
||||
|
||||
|
||||
# Store Plugins
|
||||
def store_plugins():
|
||||
customization = config['plugin_customization']
|
||||
for plugin in _initialized_plugins:
|
||||
if isinstance(plugin, Store):
|
||||
if isinstance(plugin, customize.StoreBase):
|
||||
plugin.site_customization = customization.get(plugin.name, '')
|
||||
yield plugin
|
||||
|
||||
|
||||
def available_store_plugins():
|
||||
for plugin in store_plugins():
|
||||
if not is_disabled(plugin):
|
||||
yield plugin
|
||||
yield plugin
|
||||
|
||||
|
||||
def stores():
|
||||
@@ -317,11 +226,8 @@ def available_stores():
|
||||
stores.add(plugin.name)
|
||||
return stores
|
||||
|
||||
# }}}
|
||||
|
||||
# Metadata read/write {{{
|
||||
|
||||
|
||||
# Metadata read/write
|
||||
_metadata_readers = {}
|
||||
_metadata_writers = {}
|
||||
|
||||
@@ -329,13 +235,13 @@ _metadata_writers = {}
|
||||
def reread_metadata_plugins():
|
||||
global _metadata_readers
|
||||
global _metadata_writers
|
||||
_metadata_readers = defaultdict(list)
|
||||
_metadata_writers = defaultdict(list)
|
||||
_metadata_readers = collections.defaultdict(list)
|
||||
_metadata_writers = collections.defaultdict(list)
|
||||
for plugin in _initialized_plugins:
|
||||
if isinstance(plugin, MetadataReaderPlugin):
|
||||
if isinstance(plugin, customize.MetadataReaderPlugin):
|
||||
for ft in plugin.file_types:
|
||||
_metadata_readers[ft].append(plugin)
|
||||
elif isinstance(plugin, MetadataWriterPlugin):
|
||||
elif isinstance(plugin, customize.MetadataWriterPlugin):
|
||||
for ft in plugin.file_types:
|
||||
_metadata_writers[ft].append(plugin)
|
||||
|
||||
@@ -408,109 +314,61 @@ class ForceIdentifiers(object):
|
||||
self.force_identifiers = False
|
||||
|
||||
|
||||
force_identifiers = ForceIdentifiers()
|
||||
|
||||
|
||||
def get_file_type_metadata(stream, ftype):
|
||||
mi = MetaInformation(None, None)
|
||||
mi = metadata.MetaInformation(None, None)
|
||||
|
||||
ftype = ftype.lower().strip()
|
||||
if ftype in _metadata_readers:
|
||||
for plugin in _metadata_readers[ftype]:
|
||||
if not is_disabled(plugin):
|
||||
with plugin:
|
||||
try:
|
||||
plugin.quick = quick_metadata.quick
|
||||
if hasattr(stream, 'seek'):
|
||||
stream.seek(0)
|
||||
mi = plugin.get_metadata(stream, ftype.lower().strip())
|
||||
break
|
||||
except:
|
||||
traceback.print_exc()
|
||||
continue
|
||||
with plugin:
|
||||
try:
|
||||
plugin.quick = quick_metadata.quick
|
||||
if hasattr(stream, 'seek'):
|
||||
stream.seek(0)
|
||||
mi = plugin.get_metadata(stream, ftype.lower().strip())
|
||||
break
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
continue
|
||||
return mi
|
||||
|
||||
|
||||
def set_file_type_metadata(stream, mi, ftype, report_error=None):
|
||||
fi = ForceIdentifiers()
|
||||
ftype = ftype.lower().strip()
|
||||
if ftype in _metadata_writers:
|
||||
customization = config['plugin_customization']
|
||||
for plugin in _metadata_writers[ftype]:
|
||||
if not is_disabled(plugin):
|
||||
with plugin:
|
||||
try:
|
||||
plugin.apply_null = apply_null_metadata.apply_null
|
||||
plugin.force_identifiers = force_identifiers.force_identifiers
|
||||
plugin.site_customization = customization.get(plugin.name, '')
|
||||
plugin.set_metadata(stream, mi, ftype.lower().strip())
|
||||
break
|
||||
except:
|
||||
if report_error is None:
|
||||
from ebook_converter import prints
|
||||
prints('Failed to set metadata for the', ftype.upper(), 'format of:', getattr(mi, 'title', ''), file=sys.stderr)
|
||||
traceback.print_exc()
|
||||
else:
|
||||
report_error(mi, ftype, traceback.format_exc())
|
||||
with plugin:
|
||||
try:
|
||||
plugin.apply_null = apply_null_metadata.apply_null
|
||||
plugin.force_identifiers = fi.force_identifiers
|
||||
plugin.site_customization = customization.get(
|
||||
plugin.name, '')
|
||||
plugin.set_metadata(stream, mi, ftype.lower().strip())
|
||||
break
|
||||
except Exception:
|
||||
if report_error is None:
|
||||
from ebook_converter import prints
|
||||
prints('Failed to set metadata for the', ftype.upper(),
|
||||
'format of:', getattr(mi, 'title', ''),
|
||||
file=sys.stderr)
|
||||
traceback.print_exc()
|
||||
else:
|
||||
report_error(mi, ftype, traceback.format_exc())
|
||||
|
||||
|
||||
def can_set_metadata(ftype):
|
||||
ftype = ftype.lower().strip()
|
||||
for plugin in _metadata_writers.get(ftype, ()):
|
||||
if not is_disabled(plugin):
|
||||
return True
|
||||
return True
|
||||
return False
|
||||
|
||||
# }}}
|
||||
|
||||
# Add/remove plugins {{{
|
||||
|
||||
|
||||
def add_plugin(path_to_zip_file):
|
||||
make_config_dir()
|
||||
plugin = load_plugin(path_to_zip_file)
|
||||
if plugin.name in builtin_names:
|
||||
raise NameConflict(
|
||||
'A builtin plugin with the name %r already exists' % plugin.name)
|
||||
plugin = initialize_plugin(plugin, path_to_zip_file)
|
||||
plugins = config['plugins']
|
||||
zfp = os.path.join(plugin_dir, plugin.name+'.zip')
|
||||
if os.path.exists(zfp):
|
||||
os.remove(zfp)
|
||||
shutil.copyfile(path_to_zip_file, zfp)
|
||||
plugins[plugin.name] = zfp
|
||||
config['plugins'] = plugins
|
||||
initialize_plugins()
|
||||
return plugin
|
||||
|
||||
|
||||
def remove_plugin(plugin_or_name):
|
||||
name = getattr(plugin_or_name, 'name', plugin_or_name)
|
||||
plugins = config['plugins']
|
||||
removed = False
|
||||
if name in plugins:
|
||||
removed = True
|
||||
try:
|
||||
zfp = os.path.join(plugin_dir, name+'.zip')
|
||||
if os.path.exists(zfp):
|
||||
os.remove(zfp)
|
||||
zfp = plugins[name]
|
||||
if os.path.exists(zfp):
|
||||
os.remove(zfp)
|
||||
except:
|
||||
pass
|
||||
plugins.pop(name)
|
||||
config['plugins'] = plugins
|
||||
initialize_plugins()
|
||||
return removed
|
||||
|
||||
# }}}
|
||||
|
||||
# Input/Output format plugins {{{
|
||||
|
||||
|
||||
# Input/Output format plugins
|
||||
def input_format_plugins():
|
||||
for plugin in _initialized_plugins:
|
||||
if isinstance(plugin, InputFormatPlugin):
|
||||
if isinstance(plugin, conversion.InputFormatPlugin):
|
||||
yield plugin
|
||||
|
||||
|
||||
@@ -533,16 +391,16 @@ def all_input_formats():
|
||||
def available_input_formats():
|
||||
formats = set()
|
||||
for plugin in input_format_plugins():
|
||||
if not is_disabled(plugin):
|
||||
for format in plugin.file_types:
|
||||
formats.add(format)
|
||||
formats.add('zip'), formats.add('rar')
|
||||
for format in plugin.file_types:
|
||||
formats.add(format)
|
||||
formats.add('zip')
|
||||
formats.add('rar')
|
||||
return formats
|
||||
|
||||
|
||||
def output_format_plugins():
|
||||
for plugin in _initialized_plugins:
|
||||
if isinstance(plugin, OutputFormatPlugin):
|
||||
if isinstance(plugin, conversion.OutputFormatPlugin):
|
||||
yield plugin
|
||||
|
||||
|
||||
@@ -557,27 +415,22 @@ def plugin_for_output_format(fmt):
|
||||
def available_output_formats():
|
||||
formats = set()
|
||||
for plugin in output_format_plugins():
|
||||
if not is_disabled(plugin):
|
||||
formats.add(plugin.file_type)
|
||||
formats.add(plugin.file_type)
|
||||
return formats
|
||||
|
||||
# }}}
|
||||
|
||||
# Catalog plugins {{{
|
||||
|
||||
|
||||
# Catalog plugins
|
||||
def catalog_plugins():
|
||||
for plugin in _initialized_plugins:
|
||||
if isinstance(plugin, CatalogPlugin):
|
||||
if isinstance(plugin, customize.CatalogPlugin):
|
||||
yield plugin
|
||||
|
||||
|
||||
def available_catalog_formats():
|
||||
formats = set()
|
||||
for plugin in catalog_plugins():
|
||||
if not is_disabled(plugin):
|
||||
for format in plugin.file_types:
|
||||
formats.add(format)
|
||||
for format in plugin.file_types:
|
||||
formats.add(format)
|
||||
return formats
|
||||
|
||||
|
||||
@@ -586,74 +439,15 @@ def plugin_for_catalog_format(fmt):
|
||||
if fmt.lower() in plugin.file_types:
|
||||
return plugin
|
||||
|
||||
# }}}
|
||||
|
||||
# Device plugins {{{
|
||||
|
||||
|
||||
def device_plugins(include_disabled=False):
|
||||
for plugin in _initialized_plugins:
|
||||
if isinstance(plugin, DevicePlugin):
|
||||
if include_disabled or not is_disabled(plugin):
|
||||
if platform in plugin.supported_platforms:
|
||||
if getattr(plugin, 'plugin_needs_delayed_initialization',
|
||||
False):
|
||||
plugin.do_delayed_plugin_initialization()
|
||||
yield plugin
|
||||
|
||||
|
||||
def disabled_device_plugins():
|
||||
for plugin in _initialized_plugins:
|
||||
if isinstance(plugin, DevicePlugin):
|
||||
if is_disabled(plugin):
|
||||
if platform in plugin.supported_platforms:
|
||||
yield plugin
|
||||
# }}}
|
||||
|
||||
# Metadata sources2 {{{
|
||||
|
||||
|
||||
def metadata_plugins(capabilities):
|
||||
capabilities = frozenset(capabilities)
|
||||
for plugin in all_metadata_plugins():
|
||||
if plugin.capabilities.intersection(capabilities) and \
|
||||
not is_disabled(plugin):
|
||||
yield plugin
|
||||
|
||||
|
||||
def all_metadata_plugins():
|
||||
for plugin in _initialized_plugins:
|
||||
if isinstance(plugin, Source):
|
||||
yield plugin
|
||||
|
||||
|
||||
def patch_metadata_plugins(possibly_updated_plugins):
|
||||
patches = {}
|
||||
for i, plugin in enumerate(_initialized_plugins):
|
||||
if isinstance(plugin, Source) and plugin.name in builtin_names:
|
||||
pup = possibly_updated_plugins.get(plugin.name)
|
||||
if pup is not None:
|
||||
if pup.version > plugin.version and pup.minimum_calibre_version <= numeric_version:
|
||||
patches[i] = pup(None)
|
||||
# Metadata source plugins dont use initialize() but that
|
||||
# might change in the future, so be safe.
|
||||
patches[i].initialize()
|
||||
for i, pup in patches.items():
|
||||
_initialized_plugins[i] = pup
|
||||
# }}}
|
||||
|
||||
# Editor plugins {{{
|
||||
|
||||
|
||||
# Editor plugins
|
||||
def all_edit_book_tool_plugins():
|
||||
for plugin in _initialized_plugins:
|
||||
if isinstance(plugin, EditBookToolPlugin):
|
||||
if isinstance(plugin, customize.EditBookToolPlugin):
|
||||
yield plugin
|
||||
# }}}
|
||||
|
||||
# Initialize plugins {{{
|
||||
|
||||
|
||||
# Initialize plugins
|
||||
_initialized_plugins = []
|
||||
|
||||
|
||||
@@ -665,8 +459,8 @@ def initialize_plugin(plugin, path_to_zip_file):
|
||||
except Exception:
|
||||
print('Failed to initialize plugin:', plugin.name, plugin.version)
|
||||
tb = traceback.format_exc()
|
||||
raise InvalidPlugin((_('Initialization of plugin %s failed with traceback:')
|
||||
%tb) + '\n'+tb)
|
||||
raise customize.InvalidPlugin((_('Initialization of plugin %s failed '
|
||||
'with traceback:') % tb) + '\n'+tb)
|
||||
|
||||
|
||||
def has_external_plugins():
|
||||
@@ -674,49 +468,23 @@ def has_external_plugins():
|
||||
return bool(config['plugins'])
|
||||
|
||||
|
||||
def initialize_plugins(perf=False):
|
||||
def initialize_plugins():
|
||||
global _initialized_plugins
|
||||
_initialized_plugins = []
|
||||
conflicts = [name for name in config['plugins'] if name in
|
||||
builtin_names]
|
||||
for p in conflicts:
|
||||
remove_plugin(p)
|
||||
external_plugins = config['plugins'].copy()
|
||||
for name in BLACKLISTED_PLUGINS:
|
||||
external_plugins.pop(name, None)
|
||||
ostdout, ostderr = sys.stdout, sys.stderr
|
||||
if perf:
|
||||
from collections import defaultdict
|
||||
import time
|
||||
times = defaultdict(lambda:0)
|
||||
for zfp in list(external_plugins) + builtin_plugins:
|
||||
|
||||
for zfp in list(external_plugins) + builtins.plugins:
|
||||
try:
|
||||
if not isinstance(zfp, type):
|
||||
# We have a plugin name
|
||||
pname = zfp
|
||||
zfp = os.path.join(plugin_dir, zfp+'.zip')
|
||||
if not os.path.exists(zfp):
|
||||
zfp = external_plugins[pname]
|
||||
try:
|
||||
plugin = load_plugin(zfp) if not isinstance(zfp, type) else zfp
|
||||
except PluginNotFound:
|
||||
continue
|
||||
if perf:
|
||||
st = time.time()
|
||||
plugin = initialize_plugin(plugin, None if isinstance(zfp, type) else zfp)
|
||||
if perf:
|
||||
times[plugin.name] = time.time() - st
|
||||
plugin = initialize_plugin(zfp, None)
|
||||
_initialized_plugins.append(plugin)
|
||||
except:
|
||||
except Exception:
|
||||
print('Failed to initialize plugin:', repr(zfp))
|
||||
if DEBUG:
|
||||
traceback.print_exc()
|
||||
# Prevent a custom plugin from overriding stdout/stderr as this breaks
|
||||
# ipython
|
||||
sys.stdout, sys.stderr = ostdout, ostderr
|
||||
if perf:
|
||||
for x in sorted(times, key=lambda x: times[x]):
|
||||
print('%50s: %.3f'%(x, times[x]))
|
||||
_initialized_plugins.sort(key=lambda x: x.priority, reverse=True)
|
||||
reread_filetype_plugins()
|
||||
reread_metadata_plugins()
|
||||
@@ -729,31 +497,11 @@ def initialized_plugins():
|
||||
for plugin in _initialized_plugins:
|
||||
yield plugin
|
||||
|
||||
# }}}
|
||||
|
||||
# CLI {{{
|
||||
|
||||
|
||||
def build_plugin(path):
|
||||
from ebook_converter import prints
|
||||
from ebook_converter.ptempfile import PersistentTemporaryFile
|
||||
from ebook_converter.utils.zipfile import ZipFile, ZIP_STORED
|
||||
path = str(path)
|
||||
names = frozenset(os.listdir(path))
|
||||
if '__init__.py' not in names:
|
||||
prints(path, ' is not a valid plugin')
|
||||
raise SystemExit(1)
|
||||
t = PersistentTemporaryFile(u'.zip')
|
||||
with ZipFile(t, 'w', ZIP_STORED) as zf:
|
||||
zf.add_dir(path, simple_filter=lambda x:x in {'.git', '.bzr', '.svn', '.hg'})
|
||||
t.close()
|
||||
plugin = add_plugin(t.name)
|
||||
os.remove(t.name)
|
||||
prints('Plugin updated:', plugin.name, plugin.version)
|
||||
|
||||
# CLI
|
||||
|
||||
def option_parser():
|
||||
parser = OptionParser(usage=_('''\
|
||||
parser = cfg.OptionParser(usage=_('''\
|
||||
%prog options
|
||||
|
||||
Customize calibre by loading external plugins.
|
||||
@@ -775,59 +523,3 @@ def option_parser():
|
||||
parser.add_option('--disable-plugin', default=None,
|
||||
help=_('Disable the named plugin'))
|
||||
return parser
|
||||
|
||||
|
||||
def main(args=sys.argv):
|
||||
parser = option_parser()
|
||||
if len(args) < 2:
|
||||
parser.print_help()
|
||||
return 1
|
||||
opts, args = parser.parse_args(args)
|
||||
if opts.add_plugin is not None:
|
||||
plugin = add_plugin(opts.add_plugin)
|
||||
print('Plugin added:', plugin.name, plugin.version)
|
||||
if opts.build_plugin is not None:
|
||||
build_plugin(opts.build_plugin)
|
||||
if opts.remove_plugin is not None:
|
||||
if remove_plugin(opts.remove_plugin):
|
||||
print('Plugin removed')
|
||||
else:
|
||||
print('No custom plugin named', opts.remove_plugin)
|
||||
if opts.customize_plugin is not None:
|
||||
name, custom = opts.customize_plugin.split(',')
|
||||
plugin = find_plugin(name.strip())
|
||||
if plugin is None:
|
||||
print('No plugin with the name %s exists'%name)
|
||||
return 1
|
||||
customize_plugin(plugin, custom)
|
||||
if opts.enable_plugin is not None:
|
||||
enable_plugin(opts.enable_plugin.strip())
|
||||
if opts.disable_plugin is not None:
|
||||
disable_plugin(opts.disable_plugin.strip())
|
||||
if opts.list_plugins:
|
||||
type_len = name_len = 0
|
||||
for plugin in initialized_plugins():
|
||||
type_len, name_len = max(type_len, len(plugin.type)), max(name_len, len(plugin.name))
|
||||
fmt = '%-{}s%-{}s%-15s%-15s%s'.format(type_len+1, name_len+1)
|
||||
print(fmt%tuple(('Type|Name|Version|Disabled|Site Customization'.split('|'))))
|
||||
print()
|
||||
for plugin in initialized_plugins():
|
||||
print(fmt%(
|
||||
plugin.type, plugin.name,
|
||||
plugin.version, is_disabled(plugin),
|
||||
plugin_customization(plugin)
|
||||
))
|
||||
print('\t', plugin.description)
|
||||
if plugin.is_customizable():
|
||||
try:
|
||||
print('\t', plugin.customization_help())
|
||||
except NotImplementedError:
|
||||
pass
|
||||
print()
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
# }}}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
"""
|
||||
Command line interface to conversion sub-system
|
||||
"""
|
||||
import sys, os, numbers
|
||||
from optparse import OptionGroup, Option
|
||||
from collections import OrderedDict
|
||||
import collections
|
||||
import numbers
|
||||
import optparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
from ebook_converter.utils.config import OptionParser
|
||||
from ebook_converter.utils.logging import Log
|
||||
@@ -12,10 +14,6 @@ from ebook_converter import patheq
|
||||
from ebook_converter.utils.localization import localize_user_manual_link
|
||||
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
USAGE = '%prog ' + _('''\
|
||||
input_file output_file [options]
|
||||
|
||||
@@ -110,7 +108,7 @@ def option_recommendation_to_cli_option(add_option, rec):
|
||||
)
|
||||
if opt.name in DEFAULT_TRUE_OPTIONS and rec.recommended_value is True:
|
||||
switches = ['--disable-'+opt.long_switch]
|
||||
add_option(Option(*switches, **attrs))
|
||||
add_option(optparse.Option(*switches, **attrs))
|
||||
|
||||
|
||||
def group_titles():
|
||||
@@ -156,27 +154,27 @@ def add_input_output_options(parser, plumber):
|
||||
def add_options(group, options):
|
||||
for opt in options:
|
||||
if plumber.input_fmt == 'recipe' and opt.option.long_switch == 'test':
|
||||
group(Option('--test', dest='test', action='callback', callback=recipe_test))
|
||||
group(optparse.Option('--test', dest='test', action='callback', callback=recipe_test))
|
||||
else:
|
||||
option_recommendation_to_cli_option(group, opt)
|
||||
|
||||
if input_options:
|
||||
title = group_titles()[0]
|
||||
io = OptionGroup(parser, title, _('Options to control the processing'
|
||||
io = optparse.OptionGroup(parser, title, _('Options to control the processing'
|
||||
' of the input %s file')%plumber.input_fmt)
|
||||
add_options(io.add_option, input_options)
|
||||
parser.add_option_group(io)
|
||||
|
||||
if output_options:
|
||||
title = group_titles()[1]
|
||||
oo = OptionGroup(parser, title, _('Options to control the processing'
|
||||
oo = optparse.OptionGroup(parser, title, _('Options to control the processing'
|
||||
' of the output %s')%plumber.output_fmt)
|
||||
add_options(oo.add_option, output_options)
|
||||
parser.add_option_group(oo)
|
||||
|
||||
|
||||
def add_pipeline_options(parser, plumber):
|
||||
groups = OrderedDict((
|
||||
groups = collections.OrderedDict((
|
||||
('' , ('',
|
||||
[
|
||||
'input_profile',
|
||||
@@ -254,7 +252,7 @@ def add_pipeline_options(parser, plumber):
|
||||
|
||||
for group, (desc, options) in groups.items():
|
||||
if group:
|
||||
group = OptionGroup(parser, group, desc)
|
||||
group = optparse.OptionGroup(parser, group, desc)
|
||||
parser.add_option_group(group)
|
||||
add_option = group.add_option if group != '' else parser.add_option
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import os, re, sys, shutil, pprint, json
|
||||
from functools import partial
|
||||
import functools
|
||||
import json
|
||||
import os
|
||||
import pprint
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
from ebook_converter.customize.conversion import OptionRecommendation, DummyReporter
|
||||
from ebook_converter.customize.ui import input_profiles, output_profiles, \
|
||||
@@ -11,14 +15,10 @@ from ebook_converter.ptempfile import PersistentTemporaryDirectory
|
||||
from ebook_converter.utils.date import parse_date
|
||||
from ebook_converter.utils.zipfile import ZipFile
|
||||
from ebook_converter import (extract, walk, isbytestring, filesystem_encoding,
|
||||
get_types_map)
|
||||
get_types_map)
|
||||
from ebook_converter.constants import __version__
|
||||
|
||||
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
DEBUG_README=b'''
|
||||
This debug directory contains snapshots of the e-book as it passes through the
|
||||
various stages of conversion. The stages are:
|
||||
@@ -1224,7 +1224,7 @@ OptionRecommendation(name='search_replace',
|
||||
page_break_on_body=self.output_plugin.file_type in ('mobi',
|
||||
'lit'),
|
||||
transform_css_rules=transform_css_rules,
|
||||
specializer=partial(self.output_plugin.specialize_css_for_output,
|
||||
specializer=functools.partial(self.output_plugin.specialize_css_for_output,
|
||||
self.log, self.opts))
|
||||
flattener(self.oeb, self.opts)
|
||||
self.opts._final_base_font_size = fbase
|
||||
|
||||
Reference in New Issue
Block a user