home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_1054 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  6.6 KB  |  184 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, John Schember <john@nachtimwald.com>'
  7. __docformat__ = 'restructuredtext en'
  8. import os
  9. import sys
  10. import re
  11. from optparse import OptionGroup, Option
  12. from calibre.ebooks.metadata.meta import metadata_from_formats
  13. from calibre.ebooks.metadata import authors_to_string
  14. from calibre.utils.config import OptionParser
  15. from calibre.utils.logging import Log
  16. from calibre.constants import preferred_encoding
  17. from calibre.customize.conversion import OptionRecommendation
  18. from calibre.ebooks.pdf.verify import is_valid_pdf, is_encrypted
  19. from pyPdf import PdfFileWriter, PdfFileReader
  20. USAGE = _('\n%prog %%name [options] file.pdf page_to_split_on ...\n%prog %%name [options] file.pdf page_range_to_split_on ...\n\t\nEx.\n\t\n%prog %%name file.pdf 6\n%prog %%name file.pdf 6-12\n%prog %%name file.pdf 6-12 8 10 9-20\n\nSplit a PDF.\n')
  21. OPTIONS = set([
  22.     OptionRecommendation(name = 'output', recommended_value = 'split.pdf', level = OptionRecommendation.HIGH, long_switch = 'output', short_switch = 'o', help = _('Path to output file. By default a file is created in the current directory.'))])
  23.  
  24. def print_help(parser, log):
  25.     help = parser.format_help().encode(preferred_encoding, 'replace')
  26.     log(help)
  27.  
  28.  
  29. def option_parser(name):
  30.     usage = USAGE.replace('%%name', name)
  31.     return OptionParser(usage = usage)
  32.  
  33.  
  34. def option_recommendation_to_cli_option(add_option, rec):
  35.     opt = rec.option
  36.     switches = None if opt.short_switch else []
  37.     switches.append('--' + opt.long_switch)
  38.     attrs = dict(dest = opt.name, help = opt.help, choices = opt.choices, default = rec.recommended_value)
  39.     add_option(Option(*switches, **attrs))
  40.  
  41.  
  42. def add_options(parser):
  43.     group = OptionGroup(parser, _('Split Options:'), _('Options to control the transformation of pdf'))
  44.     parser.add_option_group(group)
  45.     add_option = group.add_option
  46.     for rec in OPTIONS:
  47.         option_recommendation_to_cli_option(add_option, rec)
  48.     
  49.  
  50.  
  51. def split_pdf(in_path, pages, page_ranges, out_name, metadata = None):
  52.     pdf = PdfFileReader(open(os.path.abspath(in_path), 'rb'))
  53.     total_pages = pdf.numPages - 1
  54.     for index in pages + page_ranges:
  55.         if index in pages:
  56.             write_pdf(pdf, out_name, '%s' % (index + 1), index, total_pages, metadata)
  57.             continue
  58.         write_pdf(pdf, out_name, '%s-%s' % (index[0] + 1, index[1] + 1), index[0], index[1], metadata)
  59.     
  60.  
  61.  
  62. def write_pdf(pdf, name, suffix, start, end, metadata = None):
  63.     if metadata == None:
  64.         title = _('Unknown')
  65.         author = _('Unknown')
  66.     else:
  67.         title = metadata.title
  68.         author = authors_to_string(metadata.authors)
  69.     out_pdf = PdfFileWriter(title = title, author = author)
  70.     for page_num in range(start, end + 1):
  71.         out_pdf.addPage(pdf.getPage(page_num))
  72.     
  73.     
  74.     try:
  75.         out_file = _[1]
  76.         out_pdf.write(out_file)
  77.     finally:
  78.         pass
  79.  
  80.  
  81.  
  82. def split_args(args):
  83.     pdf = ''
  84.     pages = []
  85.     page_ranges = []
  86.     bad = []
  87.     for arg in args:
  88.         arg = arg.strip()
  89.         if re.search('(?iu)^.*?\\.pdf[ ]*$', arg) != None:
  90.             if pdf == '':
  91.                 pdf = arg
  92.             else:
  93.                 bad.append(arg)
  94.         pdf == ''
  95.         if re.search('^[ ]*\\d+[ ]*$', arg) != None:
  96.             pages.append(arg)
  97.             continue
  98.         if re.search('^[ ]*\\d+[ ]*-[ ]*\\d+[ ]*$', arg) != None:
  99.             mo = re.search('^[ ]*(?P<start>\\d+)[ ]*-[ ]*(?P<end>\\d+)[ ]*$', arg)
  100.             start = mo.group('start')
  101.             end = mo.group('end')
  102.             if start == end:
  103.                 pages.append(start)
  104.             else:
  105.                 page_ranges.append([
  106.                     start,
  107.                     end])
  108.         start == end
  109.         bad.append(arg)
  110.     
  111.     bad = sorted(list(set(bad)))
  112.     return (pdf, pages, page_ranges, bad)
  113.  
  114.  
  115. def clean_page_list(pdf_path, pages, page_ranges):
  116.     pdf = PdfFileReader(open(os.path.abspath(pdf_path), 'rb'))
  117.     total_pages = pdf.numPages
  118.     sorted_pages = []
  119.     sorted_ranges = []
  120.     for index in pages:
  121.         index = int(index)
  122.         if index > total_pages:
  123.             sorted_pages.append(total_pages - 1)
  124.             continue
  125.         sorted_pages.append(index - 1)
  126.     
  127.     for start, end in page_ranges:
  128.         start = int(start)
  129.         end = int(end)
  130.         if start > total_pages and end > total_pages:
  131.             sorted_pages.append(total_pages - 1)
  132.             continue
  133.         
  134.         if start > total_pages:
  135.             start = total_pages
  136.         
  137.         if end > total_pages:
  138.             end = total_pages
  139.         
  140.         page_range = sorted([
  141.             start - 1,
  142.             end - 1])
  143.         if page_range not in sorted_ranges:
  144.             sorted_ranges.append(page_range)
  145.             continue
  146.     
  147.     pages = sorted(list(set(sorted_pages)))
  148.     page_ranges = sorted(sorted_ranges)
  149.     return (pages, page_ranges)
  150.  
  151.  
  152. def main(args = sys.argv, name = ''):
  153.     log = Log()
  154.     parser = option_parser(name)
  155.     add_options(parser)
  156.     (opts, args) = parser.parse_args(args)
  157.     (pdf, pages, page_ranges, unknown) = split_args(args[1:])
  158.     if pdf == '':
  159.         if pages == [] or page_ranges == []:
  160.             print 'Error: PDF and where to split is required.\n'
  161.             print_help(parser, log)
  162.             return 1
  163.         if unknown != []:
  164.             for arg in unknown:
  165.                 print 'Error: Unknown argument `%s`' % arg
  166.             
  167.             print_help(parser, log)
  168.             return 1
  169.         if not is_valid_pdf(pdf):
  170.             print 'Error: Could not read file `%s`.' % pdf
  171.             return 1
  172.         if is_encrypted(pdf):
  173.             print 'Error: file `%s` is encrypted.' % args[0]
  174.             return 1
  175.         (pages, page_ranges) = clean_page_list(pdf, pages, page_ranges)
  176.         mi = metadata_from_formats([
  177.             pdf])
  178.         split_pdf(pdf, pages, page_ranges, os.path.splitext(opts.output)[0], mi)
  179.         return 0
  180.  
  181. if __name__ == '__main__':
  182.     sys.exit(main())
  183.  
  184.