home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_1358 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  9.6 KB  |  229 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__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
  7. __docformat__ = 'restructuredtext en'
  8. import os
  9. import traceback
  10. import cStringIO
  11. import re
  12. from calibre.utils.config import Config, StringConfig, tweaks
  13. from calibre.utils.filenames import shorten_components_to, supports_long_names, ascii_filename, sanitize_file_name
  14. from calibre.ebooks.metadata.opf2 import metadata_to_opf
  15. from calibre.ebooks.metadata.meta import set_metadata
  16. from calibre.constants import preferred_encoding, filesystem_encoding
  17. from calibre.ebooks.metadata import title_sort
  18. from calibre import strftime
  19. DEFAULT_TEMPLATE = '{author_sort}/{title}/{title} - {authors}'
  20. DEFAULT_SEND_TEMPLATE = '{author_sort}/{title} - {authors}'
  21. FORMAT_ARG_DESCS = dict(title = _('The title'), authors = _('The authors'), author_sort = _('The author sort string. To use only the first letter of the name use {author_sort[0]}'), tags = _('The tags'), series = _('The series'), series_index = _('The series number. To get leading zeros use {series_index:0>3s} or {series_index:>3s} for leading spaces'), rating = _('The rating'), isbn = _('The ISBN'), publisher = _('The publisher'), timestamp = _('The date'), pubdate = _('The published date'), id = _('The calibre internal id'))
  22. FORMAT_ARGS = { }
  23. for x in FORMAT_ARG_DESCS:
  24.     FORMAT_ARGS[x] = ''
  25.  
  26.  
  27. def config(defaults = None):
  28.     if defaults is None:
  29.         c = Config('save_to_disk', _('Options to control saving to disk'))
  30.     else:
  31.         c = StringConfig(defaults)
  32.     x = c.add_opt
  33.     x('update_metadata', default = True, help = _('Normally, calibre will update the metadata in the saved files from what is in the calibre library. Makes saving to disk slower.'))
  34.     x('write_opf', default = True, help = _('Normally, calibre will write the metadata into a separate OPF file along with the actual e-book files.'))
  35.     x('save_cover', default = True, help = _('Normally, calibre will save the cover in a separate file along with the actual e-book file(s).'))
  36.     x('formats', default = 'all', help = _('Comma separated list of formats to save for each book. By default all available books are saved.'))
  37.     x('template', default = DEFAULT_TEMPLATE, help = _('The template to control the filename and directory structure of the saved files. Default is "%s" which will save books into a per-author subdirectory with filenames containing title and author. Available controls are: {%s}') % (DEFAULT_TEMPLATE, ', '.join(FORMAT_ARGS)))
  38.     x('send_template', default = DEFAULT_SEND_TEMPLATE, help = _('The template to control the filename and directory structure of files sent to the device. Default is "%s" which will save books into a per-author directory with filenames containing title and author. Available controls are: {%s}') % (DEFAULT_SEND_TEMPLATE, ', '.join(FORMAT_ARGS)))
  39.     x('asciiize', default = True, help = _('Normally, calibre will convert all non English characters into English equivalents for the file names. WARNING: If you turn this off, you may experience errors when saving, depending on how well the filesystem you are saving to supports unicode.'))
  40.     x('timefmt', default = '%b, %Y', help = _('The format in which to display dates. %d - day, %b - month, %Y - year. Default is: %b, %Y'))
  41.     x('to_lowercase', default = False, help = _('Convert paths to lowercase.'))
  42.     x('replace_whitespace', default = False, help = _('Replace whitespace with underscores.'))
  43.     return c
  44.  
  45.  
  46. def preprocess_template(template):
  47.     template = template.replace('//', '/')
  48.     template = template.replace('{author}', '{authors}')
  49.     template = template.replace('{tag}', '{tags}')
  50.     if not isinstance(template, unicode):
  51.         template = template.decode(preferred_encoding, 'replace')
  52.     
  53.     return template
  54.  
  55.  
  56. def safe_format(x, format_args):
  57.     
  58.     try:
  59.         ans = x.format(**format_args).strip()
  60.         return re.sub('\\s+', ' ', ans)
  61.     except IndexError:
  62.         pass
  63.     except AttributeError:
  64.         pass
  65.  
  66.     return ''
  67.  
  68.  
  69. def get_components(template, mi, id, timefmt = '%b %Y', length = 250, sanitize_func = ascii_filename, replace_whitespace = False, to_lowercase = False):
  70.     library_order = tweaks['save_template_title_series_sorting'] == 'library_order'
  71.     tsfmt = None if library_order else (lambda x: x)
  72.     format_args = dict(**FORMAT_ARGS)
  73.     if mi.title:
  74.         format_args['title'] = tsfmt(mi.title)
  75.     
  76.     if mi.authors:
  77.         format_args['authors'] = mi.format_authors()
  78.         format_args['author'] = format_args['authors']
  79.     
  80.     if mi.author_sort:
  81.         format_args['author_sort'] = mi.author_sort
  82.     
  83.     if mi.tags:
  84.         format_args['tags'] = mi.format_tags()
  85.         if format_args['tags'].startswith('/'):
  86.             format_args['tags'] = format_args['tags'][1:]
  87.         
  88.     
  89.     if mi.series:
  90.         format_args['series'] = tsfmt(mi.series)
  91.         if mi.series_index is not None:
  92.             format_args['series_index'] = mi.format_series_index()
  93.         
  94.     else:
  95.         template = re.sub('\\{series_index[^}]*?\\}', '', template)
  96.     if mi.rating is not None:
  97.         format_args['rating'] = mi.format_rating()
  98.     
  99.     if mi.isbn:
  100.         format_args['isbn'] = mi.isbn
  101.     
  102.     if mi.publisher:
  103.         format_args['publisher'] = mi.publisher
  104.     
  105.     if hasattr(mi.timestamp, 'timetuple'):
  106.         format_args['timestamp'] = strftime(timefmt, mi.timestamp.timetuple())
  107.     
  108.     if hasattr(mi.pubdate, 'timetuple'):
  109.         format_args['pubdate'] = strftime(timefmt, mi.pubdate.timetuple())
  110.     
  111.     format_args['id'] = str(id)
  112.     components = _[1]
  113.     components = [ safe_format(x, format_args) for x in components ]
  114.     components = _[3]
  115.     components = [ _[4] if isinstance(x, unicode) else x for x in components ]
  116.     return shorten_components_to(length, components)
  117.  
  118.  
  119. def save_book_to_disk(id, db, root, opts, length):
  120.     mi = db.get_metadata(id, index_is_id = True)
  121.     available_formats = db.formats(id, index_is_id = True)
  122.     formats = set(available_formats).intersection(set(asked_formats))
  123.     if not formats:
  124.         return (True, id, mi.title)
  125.     components = formats(get_components, opts.template, mi, id, opts.timefmt, length if opts.asciiize else sanitize_file_name, to_lowercase = opts.to_lowercase, replace_whitespace = opts.replace_whitespace)
  126.     base_path = os.path.join(root, *components)
  127.     base_name = os.path.basename(base_path)
  128.     dirpath = os.path.dirname(base_path)
  129.     
  130.     try:
  131.         os.makedirs(dirpath)
  132.     except BaseException:
  133.         [] if opts.formats == 'all' else []
  134.         [] if opts.formats == 'all' else []
  135.         if not os.path.exists(dirpath):
  136.             raise 
  137.         os.path.exists(dirpath)
  138.     except:
  139.         [] if opts.formats == 'all' else []
  140.  
  141.     cdata = db.cover(id, index_is_id = True)
  142.     if opts.save_cover:
  143.         if cdata is not None:
  144.             
  145.             try:
  146.                 f = _[3]
  147.                 f.write(cdata)
  148.             finally:
  149.                 pass
  150.  
  151.             mi.cover = base_name + '.jpg'
  152.         else:
  153.             mi.cover = None
  154.     
  155.     if cdata is not None:
  156.         mi.cover_data = ('jpg', cdata)
  157.     
  158.     mi.cover = None
  159.     written = False
  160.     for fmt in formats:
  161.         data = db.format(id, fmt, index_is_id = True)
  162.         if data is None:
  163.             continue
  164.         else:
  165.             written = True
  166.         if opts.update_metadata:
  167.             stream = cStringIO.StringIO()
  168.             stream.write(data)
  169.             stream.seek(0)
  170.             
  171.             try:
  172.                 set_metadata(stream, mi, fmt)
  173.             except:
  174.                 traceback.print_exc()
  175.  
  176.             stream.seek(0)
  177.             data = stream.read()
  178.         
  179.         fmt_path = base_path + '.' + str(fmt)
  180.         
  181.         try:
  182.             f = _[5]
  183.             f.write(data)
  184.         finally:
  185.             pass
  186.  
  187.     
  188.     return (not written, id, mi.title)
  189.  
  190.  
  191. def save_to_disk(db, ids, root, opts = None, callback = None):
  192.     if opts is None:
  193.         opts = config().parse()
  194.     
  195.     if isinstance(root, unicode):
  196.         root = root.encode(filesystem_encoding)
  197.     
  198.     root = os.path.abspath(root)
  199.     opts.template = preprocess_template(opts.template)
  200.     length = None if supports_long_names(root) else 250
  201.     length -= len(root)
  202.     if length < 5:
  203.         raise ValueError('%r is too long.' % root)
  204.     length < 5
  205.     failures = []
  206.     for x in ids:
  207.         tb = ''
  208.         
  209.         try:
  210.             (failed, id, title) = save_book_to_disk(x, db, root, opts, length)
  211.             tb = _('Requested formats not available')
  212.         except:
  213.             failed = True
  214.             id = x
  215.             title = db.title(x, index_is_id = True)
  216.             tb = traceback.format_exc()
  217.  
  218.         if failed:
  219.             failures.append((id, title, tb))
  220.         
  221.         if callable(callback):
  222.             if not callback(int(id), title, failed, tb):
  223.                 break
  224.             
  225.         callback(int(id), title, failed, tb)
  226.     
  227.     return failures
  228.  
  229.