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