bgneal@591: """make_fixed_page.py
bgneal@584: 
bgneal@591: A management command to generate HTML files that can be {% include'd %} by a
bgneal@591: generic flatpage-like system. We currently support restructured text as input.
bgneal@591: 
bgneal@591: I chose "fixed" page since I didn't want to confuse this with Django's flatpage
bgneal@591: system.
bgneal@591: 
bgneal@591: This command reads input files from the directory PROJECT_PATH/fixed and writes
bgneal@591: the HTML output to PROJECT_PATH/templates/fixed.
bgneal@584: 
bgneal@584: """
bgneal@587: from __future__ import with_statement
bgneal@584: import os.path
bgneal@591: import glob
bgneal@584: 
bgneal@584: import docutils.core
bgneal@584: from django.core.management.base import LabelCommand, CommandError
bgneal@584: from django.conf import settings
bgneal@584: 
bgneal@584: 
bgneal@584: class Command(LabelCommand):
bgneal@591:     help = "Generate HTML from restructured text files"
bgneal@584:     args = "<inputfile1> <inputfile2> ... | all"
bgneal@584: 
bgneal@584:     def handle_label(self, filename, **kwargs):
bgneal@584:         """Process input file(s)"""
bgneal@584: 
bgneal@584:         if not hasattr(settings, 'PROJECT_PATH'):
bgneal@584:             raise CommandError("Please add a PROJECT_PATH setting")
bgneal@584: 
bgneal@591:         self.src_dir = os.path.join(settings.PROJECT_PATH, 'fixed')
bgneal@591:         self.dst_dir = os.path.join(settings.PROJECT_PATH, 'templates', 'fixed')
bgneal@584: 
bgneal@584:         if filename == 'all':
bgneal@591:             files = glob.glob("%s%s*.rst" % (self.src_dir, os.path.sep))
bgneal@591:             files = [os.path.basename(f) for f in files]
bgneal@584:         else:
bgneal@584:             files = [filename]
bgneal@584: 
bgneal@584:         for f in files:
bgneal@591:             self.process_page(f)
bgneal@584: 
bgneal@591:     def process_page(self, filename):
bgneal@591:         """Processes one fixed page"""
bgneal@584: 
bgneal@584:         # retrieve source text
bgneal@584:         src_path = os.path.join(self.src_dir, filename)
bgneal@591:         try:
bgneal@591:             with open(src_path, 'r') as f:
bgneal@591:                 src_text = f.read()
bgneal@591:         except IOError, ex:
bgneal@591:             raise CommandError(str(ex))
bgneal@584: 
bgneal@584:         # transform text
bgneal@584:         content = self.transform_input(src_text)
bgneal@584: 
bgneal@591:         # write output
bgneal@591:         basename = os.path.splitext(os.path.basename(filename))[0]
bgneal@591:         dst_path = os.path.join(self.dst_dir, '%s.html' % basename)
bgneal@584: 
bgneal@584:         try:
bgneal@591:             with open(dst_path, 'w') as f:
bgneal@591:                 f.write(content.encode('utf-8'))
bgneal@591:         except IOError, ex:
bgneal@591:             raise CommandError(str(ex))
bgneal@584: 
bgneal@591:         prefix = os.path.commonprefix([src_path, dst_path])
bgneal@591:         self.stdout.write("%s -> %s\n" % (filename, dst_path[len(prefix):]))
bgneal@584: 
bgneal@584:     def transform_input(self, src_text):
bgneal@584:         """Transforms input restructured text to HTML"""
bgneal@584: 
bgneal@584:         return docutils.core.publish_parts(src_text, writer_name='html',
bgneal@584:                 settings_overrides={
bgneal@584:                     'doctitle_xform': False,
bgneal@591:                     'initial_header_level': 2,
bgneal@584:                     })['html_body']