Page Source

from utils.controls import *
from utils.output import html
from utils import output
from mod_python import apache
from utils.display import Display, Database, Arguments
from utils.display import Modal
from utils.web_exc import WebError, SendLiteral
from utils import bounce
from utils.static_strings import StaticString
from config import docroot
import string, os
import debugging

class UnfinishedStarControl(MultipleControl):
  """Draw a star for unfinished asides, identified because their body
  is 'Coming Soon'."""
  def output_disp(self, display, container):
    if display.fields['body'] == 'Coming Soon':
      container.append("<sup>*</sup>")

###################
# The display class itself

class AsideDisplay(Display, StaticString, Database, Arguments, Modal):
  def __init__(self, req):
    Display.__init__(self, req)

  def process_arguments(self):
    if not hasattr(self, 'args'):
      self.args = self.parse_arguments(['aside_name'])
      if self.args['aside_name'] and \
         not self.check_name_characters(self.args['aside_name']):
        self.args['aside_name'] = None
        
  def perform_action(self):
    self.process_arguments()
    self.prep_database()
    
    if self.permit_mode('edit') and not self.is_multiple():
      # Edit
      self.perform_database_update()
      return "%(aside!aside_name)s" \
             % self.req.urls( { 'aside_name' : self.args['aside_name'] } )
       
  def make_page(self, page):
    self.process_arguments()

    self.prep_database()

    page.set_type("info")

    # Check to see if we need to give the user *just* the body
    # in text format
    if not self.is_multiple() and self.req.url.internal.has_key('body'):
      raise SendLiteral('text/plain', self.fields['body'])
    elif self.is_multiple():
      page.set_title(self.get_multiple_title())
      page.append("<h1>%s</h1>\n" % self.get_multiple_title())
      page.add_navigation("%(documentation)s" % self.req.urls(self.args),
                          "Site Documentation")
      # a nice note about how asides work
      if self.req.login:
        page.append(self.GetString(key="services_website_aside",
                                     display=self))
      page.append(self.multiple_database())
    else:
      self.add_modes_to_page(page)
      page.set_title(self.get_single_title())
      page.add_navigation("%(documentation)s" % self.req.urls(self.args),
                          "Site Documentation")
      page.add_navigation("%(aside:)s" % self.req.urls(self.args),
                          "All Asides")
      if self.get_mode() == 'edit':
        self.shape = shapes.FORM
      page.append(self.single_database())

  def permit_mode(self, mode):
    return ((mode == 'display') or
            (mode == 'edit') and perms.may(self.req.login, 'edit', 'documentation'))

  _name_characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-."
  def check_name_characters(self, name):
    """Check a name to be sure it's URL-OK."""
    if len(name) > 20:
      return None                       # too long
    for char in name:
      if char not in self._name_characters:
        return None                     # not OK
    return 1                            # OK

  multiple_container_control = CoalesceContainerControl(
    [ BulletColumnsContainerControl(),
      "Note: <sup>*</sup> denotes unfinished asides", ],
    representative=0)                   # first element in list gets subcontainers
  multiple_controls = [
    CoalesceControl(
    [ UnfinishedStarControl(),
      LinkControl("aside_name",
                  "%(aside!aside_name)s",
                  FieldControl("title")),
      ]),
    ]

  def get_multiple_title(self):
    return "Asides"

  single_controls = [
    IfShapeControl(formcontrols=[ NoEditControl("aside_name", title="Aside Identifier") ] ),
    "<h1>", TextFieldControl("title", title="Title"), "</h1>",
    DropCapControl(HTMLEditorControl("body",
                                        "%(aside!aside_name)s?body=txt",
                                        title="Body", rows=35, cols=80)),
    ]

  def get_single_title(self):
    return self.fields['title']

  def db_query(self):
    wc = []
    if self.args['aside_name']:
      wc.append("aside_name = %s" % queries.represent_value(self.args['aside_name']))

    s = queries.Select(tables=["doc_asides"],
                       order="title",
                       where=string.join(wc, ' AND '),
                       columns=['title', 'aside_name', 'body'])
    s.execute()
    self.query = s

  def is_multiple(self):
    return not self.args['aside_name']

  def db_fetch(self):
    # if there were no results and we're not multiple, then this is a *new*
    # aside, so make up some fake data.
    if not self.is_multiple() and self.db_rows() == 0:
      self.fields = { 'title' : self.args['aside_name'],
                      'aside_name' : self.args['aside_name'],
                      'body' : 'Coming Soon' }
    else:
      self.fields = self.query.fetch()
    return self.fields

  def db_update(self):
    i = queries.Insert(table="doc_asides",
                       rows=[{'aside_name' : self.args['aside_name'],
                              'title' : self.form_fields['title'],
                              'body' : self.form_fields['body']}])
    i.replace()
    i.execute()

  def db_rows(self):
    return self.query.count()

def new(req):
  return AsideDisplay(req)