home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_721 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  20.0 KB  |  634 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. from __future__ import with_statement
  5. __license__ = 'GPL v3'
  6. __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
  7. import os
  8. import shutil
  9. import traceback
  10. import functools
  11. import sys
  12. import re
  13. from contextlib import closing
  14. from calibre.customize import Plugin, CatalogPlugin, FileTypePlugin, MetadataReaderPlugin, MetadataWriterPlugin
  15. from calibre.customize.conversion import InputFormatPlugin, OutputFormatPlugin
  16. from calibre.customize.profiles import InputProfile, OutputProfile
  17. from calibre.customize.builtins import plugins as builtin_plugins
  18. from calibre.constants import numeric_version as version, iswindows, isosx
  19. from calibre.devices.interface import DevicePlugin
  20. from calibre.ebooks.metadata import MetaInformation
  21. from calibre.ebooks.metadata.covers import CoverDownload
  22. from calibre.ebooks.metadata.fetch import MetadataSource
  23. from calibre.utils.config import make_config_dir, Config, ConfigProxy, plugin_dir, OptionParser, prefs
  24. from calibre.ebooks.epub.fix import ePubFixer
  25. platform = 'linux'
  26. if iswindows:
  27.     platform = 'windows'
  28. elif isosx:
  29.     platform = 'osx'
  30.  
  31. from zipfile import ZipFile
  32.  
  33. def _config():
  34.     c = Config('customize')
  35.     c.add_opt('plugins', default = { }, help = _('Installed plugins'))
  36.     c.add_opt('filetype_mapping', default = { }, help = _('Mapping for filetype plugins'))
  37.     c.add_opt('plugin_customization', default = { }, help = _('Local plugin customization'))
  38.     c.add_opt('disabled_plugins', default = set([]), help = _('Disabled plugins'))
  39.     c.add_opt('enabled_plugins', default = set([]), help = _('Enabled plugins'))
  40.     return ConfigProxy(c)
  41.  
  42. config = _config()
  43.  
  44. class InvalidPlugin(ValueError):
  45.     pass
  46.  
  47.  
  48. class PluginNotFound(ValueError):
  49.     pass
  50.  
  51.  
  52. def find_plugin(name):
  53.     for plugin in _initialized_plugins:
  54.         if plugin.name == name:
  55.             return plugin
  56.     
  57.  
  58.  
  59. def load_plugin(path_to_zip_file):
  60.     if not os.access(path_to_zip_file, os.R_OK):
  61.         raise PluginNotFound
  62.     os.access(path_to_zip_file, os.R_OK)
  63.     
  64.     try:
  65.         zf = _[1]
  66.         for name in zf.namelist():
  67.             if name.lower().endswith('plugin.py'):
  68.                 locals = { }
  69.                 raw = zf.read(name)
  70.                 match = re.search('coding[:=]\\s*([-\\w.]+)', raw[:300])
  71.                 encoding = 'utf-8'
  72.                 raw = raw.decode(encoding)
  73.                 raw = re.sub('\r\n', '\n', raw)
  74.                 exec raw in locals
  75.                 for x in locals.values():
  76.                     if isinstance(x, type) and issubclass(x, Plugin) and x.name != 'Trivial Plugin':
  77.                         if x.minimum_calibre_version > version or platform not in x.supported_platforms:
  78.                             continue
  79.                         
  80.                         return x
  81.                 
  82.             x.name != 'Trivial Plugin'
  83.     finally:
  84.         pass
  85.  
  86.     raise InvalidPlugin(_('No valid plugin found in ') + path_to_zip_file)
  87.  
  88.  
  89. def disable_plugin(plugin_or_name):
  90.     x = getattr(plugin_or_name, 'name', plugin_or_name)
  91.     plugin = find_plugin(x)
  92.     if not plugin.can_be_disabled:
  93.         raise ValueError('Plugin %s cannot be disabled' % x)
  94.     plugin.can_be_disabled
  95.     dp = config['disabled_plugins']
  96.     dp.add(x)
  97.     config['disabled_plugins'] = dp
  98.     ep = config['enabled_plugins']
  99.     if x in ep:
  100.         ep.remove(x)
  101.     
  102.     config['enabled_plugins'] = ep
  103.  
  104.  
  105. def enable_plugin(plugin_or_name):
  106.     x = getattr(plugin_or_name, 'name', plugin_or_name)
  107.     dp = config['disabled_plugins']
  108.     if x in dp:
  109.         dp.remove(x)
  110.     
  111.     config['disabled_plugins'] = dp
  112.     ep = config['enabled_plugins']
  113.     ep.add(x)
  114.     config['enabled_plugins'] = ep
  115.  
  116. default_disabled_plugins = set([
  117.     'Douban Books'])
  118.  
  119. def is_disabled(plugin):
  120.     if plugin.name in config['enabled_plugins']:
  121.         return False
  122.     if not plugin.name in config['disabled_plugins']:
  123.         pass
  124.     return plugin.name in default_disabled_plugins
  125.  
  126. _on_import = { }
  127. _on_preprocess = { }
  128. _on_postprocess = { }
  129.  
  130. def reread_filetype_plugins():
  131.     global _on_import, _on_preprocess, _on_postprocess
  132.     _on_import = { }
  133.     _on_preprocess = { }
  134.     _on_postprocess = { }
  135.     for plugin in _initialized_plugins:
  136.         if isinstance(plugin, FileTypePlugin):
  137.             for ft in plugin.file_types:
  138.                 if plugin.on_import:
  139.                     if not _on_import.has_key(ft):
  140.                         _on_import[ft] = []
  141.                     
  142.                     _on_import[ft].append(plugin)
  143.                 
  144.                 if plugin.on_preprocess:
  145.                     if not _on_preprocess.has_key(ft):
  146.                         _on_preprocess[ft] = []
  147.                     
  148.                     _on_preprocess[ft].append(plugin)
  149.                 
  150.                 if plugin.on_postprocess:
  151.                     if not _on_postprocess.has_key(ft):
  152.                         _on_postprocess[ft] = []
  153.                     
  154.                     _on_postprocess[ft].append(plugin)
  155.                     continue
  156.             
  157.     
  158.  
  159.  
  160. def _run_filetype_plugins(path_to_file, ft = None, occasion = 'preprocess'):
  161.     occasion_plugins = {
  162.         'import': _on_import,
  163.         'preprocess': _on_preprocess,
  164.         'postprocess': _on_postprocess }[occasion]
  165.     customization = config['plugin_customization']
  166.     if ft is None:
  167.         ft = os.path.splitext(path_to_file)[-1].lower().replace('.', '')
  168.     
  169.     nfp = path_to_file
  170.     for plugin in occasion_plugins.get(ft, []):
  171.         if is_disabled(plugin):
  172.             continue
  173.         
  174.         plugin.site_customization = customization.get(plugin.name, '')
  175.         plugin.__enter__()
  176.         
  177.         try:
  178.             nfp = plugin.run(path_to_file)
  179.             if not nfp:
  180.                 nfp = path_to_file
  181.         except:
  182.             plugin.__exit__
  183.             plugin
  184.             print 'Running file type plugin %s failed with traceback:' % plugin.name
  185.             traceback.print_exc()
  186.         finally:
  187.             pass
  188.  
  189.     
  190.     
  191.     x = lambda j: os.path.normpath(os.path.normcase(j))
  192.     return nfp
  193.  
  194. run_plugins_on_import = functools.partial(_run_filetype_plugins, occasion = 'import')
  195. run_plugins_on_preprocess = functools.partial(_run_filetype_plugins, occasion = 'preprocess')
  196. run_plugins_on_postprocess = functools.partial(_run_filetype_plugins, occasion = 'postprocess')
  197.  
  198. def customize_plugin(plugin, custom):
  199.     d = config['plugin_customization']
  200.     d[plugin.name] = custom.strip()
  201.     config['plugin_customization'] = d
  202.  
  203.  
  204. def plugin_customization(plugin):
  205.     return config['plugin_customization'].get(plugin.name, '')
  206.  
  207.  
  208. def input_profiles():
  209.     for plugin in _initialized_plugins:
  210.         if isinstance(plugin, InputProfile):
  211.             yield plugin
  212.             continue
  213.     
  214.  
  215.  
  216. def output_profiles():
  217.     for plugin in _initialized_plugins:
  218.         if isinstance(plugin, OutputProfile):
  219.             yield plugin
  220.             continue
  221.     
  222.  
  223.  
  224. def metadata_sources(metadata_type = 'basic', customize = True, isbndb_key = None):
  225.     for plugin in _initialized_plugins:
  226.         if isinstance(plugin, MetadataSource) and plugin.metadata_type == metadata_type:
  227.             if is_disabled(plugin):
  228.                 continue
  229.             
  230.             if customize:
  231.                 customization = config['plugin_customization']
  232.                 plugin.site_customization = customization.get(plugin.name, None)
  233.             
  234.             if plugin.name == 'IsbnDB' and isbndb_key is not None:
  235.                 plugin.site_customization = isbndb_key
  236.             
  237.             yield plugin
  238.             continue
  239.     
  240.  
  241.  
  242. def get_isbndb_key():
  243.     return config['plugin_customization'].get('IsbnDB', None)
  244.  
  245.  
  246. def set_isbndb_key(key):
  247.     for plugin in _initialized_plugins:
  248.         if plugin.name == 'IsbnDB':
  249.             return customize_plugin(plugin, key)
  250.     
  251.  
  252.  
  253. def migrate_isbndb_key():
  254.     key = prefs['isbndb_com_key']
  255.     if key:
  256.         prefs.set('isbndb_com_key', '')
  257.         set_isbndb_key(key)
  258.     
  259.  
  260.  
  261. def cover_sources():
  262.     customization = config['plugin_customization']
  263.     for plugin in _initialized_plugins:
  264.         if isinstance(plugin, CoverDownload):
  265.             if not is_disabled(plugin):
  266.                 plugin.site_customization = customization.get(plugin.name, '')
  267.                 yield plugin
  268.             
  269.         is_disabled(plugin)
  270.     
  271.  
  272. _metadata_readers = { }
  273. _metadata_writers = { }
  274.  
  275. def reread_metadata_plugins():
  276.     global _metadata_readers
  277.     _metadata_readers = { }
  278.     for plugin in _initialized_plugins:
  279.         if isinstance(plugin, MetadataReaderPlugin):
  280.             for ft in plugin.file_types:
  281.                 if not _metadata_readers.has_key(ft):
  282.                     _metadata_readers[ft] = []
  283.                 
  284.                 _metadata_readers[ft].append(plugin)
  285.             
  286.         if isinstance(plugin, MetadataWriterPlugin):
  287.             for ft in plugin.file_types:
  288.                 if not _metadata_writers.has_key(ft):
  289.                     _metadata_writers[ft] = []
  290.                 
  291.                 _metadata_writers[ft].append(plugin)
  292.             
  293.     
  294.  
  295.  
  296. def metadata_readers():
  297.     ans = set([])
  298.     for plugins in _metadata_readers.values():
  299.         for plugin in plugins:
  300.             ans.add(plugin)
  301.         
  302.     
  303.     return ans
  304.  
  305.  
  306. def metadata_writers():
  307.     ans = set([])
  308.     for plugins in _metadata_writers.values():
  309.         for plugin in plugins:
  310.             ans.add(plugin)
  311.         
  312.     
  313.     return ans
  314.  
  315.  
  316. class QuickMetadata(object):
  317.     
  318.     def __init__(self):
  319.         self.quick = False
  320.  
  321.     
  322.     def __enter__(self):
  323.         self.quick = True
  324.  
  325.     
  326.     def __exit__(self, *args):
  327.         self.quick = False
  328.  
  329.  
  330. quick_metadata = QuickMetadata()
  331.  
  332. class ApplyNullMetadata(object):
  333.     
  334.     def __init__(self):
  335.         self.apply_null = False
  336.  
  337.     
  338.     def __enter__(self):
  339.         self.apply_null = True
  340.  
  341.     
  342.     def __exit__(self, *args):
  343.         self.apply_null = False
  344.  
  345.  
  346. apply_null_metadata = ApplyNullMetadata()
  347.  
  348. def get_file_type_metadata(stream, ftype):
  349.     mi = MetaInformation(None, None)
  350.     ftype = ftype.lower().strip()
  351.     if _metadata_readers.has_key(ftype):
  352.         for plugin in _metadata_readers[ftype]:
  353.             if not is_disabled(plugin):
  354.                 plugin.__enter__()
  355.                 
  356.                 try:
  357.                     plugin.quick = quick_metadata.quick
  358.                     mi = plugin.get_metadata(stream, ftype.lower().strip())
  359.                 except:
  360.                     plugin.__exit__
  361.                     plugin
  362.                     traceback.print_exc()
  363.                     continue
  364.                 finally:
  365.                     pass
  366.  
  367.                 continue
  368.             plugin.__exit__
  369.         
  370.     
  371.     return mi
  372.  
  373.  
  374. def set_file_type_metadata(stream, mi, ftype):
  375.     ftype = ftype.lower().strip()
  376.     if _metadata_writers.has_key(ftype):
  377.         for plugin in _metadata_writers[ftype]:
  378.             if not is_disabled(plugin):
  379.                 plugin.__enter__()
  380.                 
  381.                 try:
  382.                     plugin.apply_null = apply_null_metadata.apply_null
  383.                     plugin.set_metadata(stream, mi, ftype.lower().strip())
  384.                 except:
  385.                     plugin.__exit__
  386.                     plugin
  387.                     print 'Failed to set metadata for', repr(getattr(mi, 'title', ''))
  388.                     traceback.print_exc()
  389.                 finally:
  390.                     pass
  391.  
  392.                 continue
  393.             plugin.__exit__
  394.         
  395.     
  396.  
  397.  
  398. def add_plugin(path_to_zip_file):
  399.     make_config_dir()
  400.     plugin = load_plugin(path_to_zip_file)
  401.     plugin = initialize_plugin(plugin, path_to_zip_file)
  402.     plugins = config['plugins']
  403.     zfp = os.path.join(plugin_dir, plugin.name + '.zip')
  404.     if os.path.exists(zfp):
  405.         os.remove(zfp)
  406.     
  407.     shutil.copyfile(path_to_zip_file, zfp)
  408.     plugins[plugin.name] = zfp
  409.     config['plugins'] = plugins
  410.     initialize_plugins()
  411.     return plugin
  412.  
  413.  
  414. def remove_plugin(plugin_or_name):
  415.     name = getattr(plugin_or_name, 'name', plugin_or_name)
  416.     plugins = config['plugins']
  417.     removed = False
  418.     if name in plugins.keys():
  419.         removed = True
  420.         zfp = plugins[name]
  421.         if os.path.exists(zfp):
  422.             os.remove(zfp)
  423.         
  424.         plugins.pop(name)
  425.     
  426.     config['plugins'] = plugins
  427.     initialize_plugins()
  428.     return removed
  429.  
  430.  
  431. def input_format_plugins():
  432.     for plugin in _initialized_plugins:
  433.         if isinstance(plugin, InputFormatPlugin):
  434.             yield plugin
  435.             continue
  436.     
  437.  
  438.  
  439. def plugin_for_input_format(fmt):
  440.     customization = config['plugin_customization']
  441.     for plugin in input_format_plugins():
  442.         if fmt.lower() in plugin.file_types:
  443.             plugin.site_customization = customization.get(plugin.name, None)
  444.             return plugin
  445.     
  446.  
  447.  
  448. def all_input_formats():
  449.     formats = set([])
  450.     for plugin in input_format_plugins():
  451.         for format in plugin.file_types:
  452.             formats.add(format)
  453.         
  454.     
  455.     return formats
  456.  
  457.  
  458. def available_input_formats():
  459.     formats = set([])
  460.     for plugin in input_format_plugins():
  461.         if not is_disabled(plugin):
  462.             for format in plugin.file_types:
  463.                 formats.add(format)
  464.             
  465.     
  466.     (formats.add('zip'), formats.add('rar'))
  467.     return formats
  468.  
  469.  
  470. def output_format_plugins():
  471.     for plugin in _initialized_plugins:
  472.         if isinstance(plugin, OutputFormatPlugin):
  473.             yield plugin
  474.             continue
  475.     
  476.  
  477.  
  478. def plugin_for_output_format(fmt):
  479.     customization = config['plugin_customization']
  480.     for plugin in output_format_plugins():
  481.         if fmt.lower() == plugin.file_type:
  482.             plugin.site_customization = customization.get(plugin.name, None)
  483.             return plugin
  484.     
  485.  
  486.  
  487. def available_output_formats():
  488.     formats = set([])
  489.     for plugin in output_format_plugins():
  490.         if not is_disabled(plugin):
  491.             formats.add(plugin.file_type)
  492.             continue
  493.     
  494.     return formats
  495.  
  496.  
  497. def catalog_plugins():
  498.     for plugin in _initialized_plugins:
  499.         if isinstance(plugin, CatalogPlugin):
  500.             yield plugin
  501.             continue
  502.     
  503.  
  504.  
  505. def available_catalog_formats():
  506.     formats = set([])
  507.     for plugin in catalog_plugins():
  508.         if not is_disabled(plugin):
  509.             for format in plugin.file_types:
  510.                 formats.add(format)
  511.             
  512.     
  513.     return formats
  514.  
  515.  
  516. def plugin_for_catalog_format(fmt):
  517.     for plugin in catalog_plugins():
  518.         if fmt.lower() in plugin.file_types:
  519.             return plugin
  520.     
  521.  
  522.  
  523. def device_plugins():
  524.     for plugin in _initialized_plugins:
  525.         if isinstance(plugin, DevicePlugin):
  526.             if not is_disabled(plugin):
  527.                 if platform in plugin.supported_platforms:
  528.                     yield plugin
  529.                 
  530.             
  531.         is_disabled(plugin)
  532.     
  533.  
  534.  
  535. def epub_fixers():
  536.     for plugin in _initialized_plugins:
  537.         if isinstance(plugin, ePubFixer):
  538.             if not is_disabled(plugin):
  539.                 if platform in plugin.supported_platforms:
  540.                     yield plugin
  541.                 
  542.             
  543.         is_disabled(plugin)
  544.     
  545.  
  546. _initialized_plugins = []
  547.  
  548. def initialize_plugin(plugin, path_to_zip_file):
  549.     
  550.     try:
  551.         p = plugin(path_to_zip_file)
  552.         p.initialize()
  553.         return p
  554.     except Exception:
  555.         print 'Failed to initialize plugin:', plugin.name, plugin.version
  556.         tb = traceback.format_exc()
  557.         raise InvalidPlugin(_('Initialization of plugin %s failed with traceback:') % tb + '\n' + tb)
  558.  
  559.  
  560.  
  561. def initialize_plugins():
  562.     global _initialized_plugins
  563.     _initialized_plugins = []
  564.     for zfp in list(config['plugins'].values()) + builtin_plugins:
  565.         
  566.         try:
  567.             
  568.             try:
  569.                 plugin = None if not isinstance(zfp, type) else zfp
  570.             except PluginNotFound:
  571.                 continue
  572.  
  573.             plugin = None(initialize_plugin, plugin if isinstance(zfp, type) else zfp)
  574.             _initialized_plugins.append(plugin)
  575.         continue
  576.         print 'Failed to initialize plugin...'
  577.         traceback.print_exc()
  578.         continue
  579.  
  580.     
  581.     _initialized_plugins.sort(cmp = (lambda x, y: cmp(x.priority, y.priority)), reverse = True)
  582.     reread_filetype_plugins()
  583.     reread_metadata_plugins()
  584.  
  585. initialize_plugins()
  586.  
  587. def initialized_plugins():
  588.     for plugin in _initialized_plugins:
  589.         yield plugin
  590.     
  591.  
  592.  
  593. def option_parser():
  594.     parser = OptionParser(usage = _('    %prog options\n\n    Customize calibre by loading external plugins.\n    '))
  595.     parser.add_option('-a', '--add-plugin', default = None, help = _('Add a plugin by specifying the path to the zip file containing it.'))
  596.     parser.add_option('-r', '--remove-plugin', default = None, help = _('Remove a custom plugin by name. Has no effect on builtin plugins'))
  597.     parser.add_option('--customize-plugin', default = None, help = _('Customize plugin. Specify name of plugin and customization string separated by a comma.'))
  598.     parser.add_option('-l', '--list-plugins', default = False, action = 'store_true', help = _('List all installed plugins'))
  599.     parser.add_option('--enable-plugin', default = None, help = _('Enable the named plugin'))
  600.     parser.add_option('--disable-plugin', default = None, help = _('Disable the named plugin'))
  601.     return parser
  602.  
  603.  
  604. def main(args = sys.argv):
  605.     parser = option_parser()
  606.     if len(args) < 2:
  607.         parser.print_help()
  608.         return 1
  609.     (opts, args) = parser.parse_args(args)
  610.     if opts.enable_plugin is not None:
  611.         enable_plugin(opts.enable_plugin.strip())
  612.     
  613.     if opts.disable_plugin is not None:
  614.         disable_plugin(opts.disable_plugin.strip())
  615.     
  616.     if opts.list_plugins:
  617.         fmt = '%-15s%-20s%-15s%-15s%s'
  618.         print fmt % tuple('Type|Name|Version|Disabled|Site Customization'.split('|'))
  619.         print 
  620.         for plugin in initialized_plugins():
  621.             print fmt % (plugin.type, plugin.name, plugin.version, is_disabled(plugin), plugin_customization(plugin))
  622.             print '\t', plugin.description
  623.             if plugin.is_customizable():
  624.                 print '\t', plugin.customization_help()
  625.             
  626.             print 
  627.         
  628.     
  629.     return 0
  630.  
  631. if __name__ == '__main__':
  632.     sys.exit(main())
  633.  
  634.