#!/usr/bin/env python2.3
# -*- coding: utf-8 -*-
#
# Copyright 2010 British Broadcasting Corporation and Kamaelia Contributors(1)
#
# (1) Kamaelia Contributors are listed in the AUTHORS file and at
#     http://www.kamaelia.org/AUTHORS - please extend this file,
#     not this notice.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# -------------------------------------------------------------------------
"""
Moved from Kamaelia.Protocol.HTTPServer.py to here since it's a) incomplete
b) Tries to do too much at this stage.
 
This was an abortive attempt by Joseph to implement a simple HTTP server.
This became a classic case of "DoingTooMuch".
 
Simple HTTP server
 
API Needs:
 
1) We don't/can't recieve notification from the ReadFileAdaptor that the
   file has been closed.
2) We can't actually tell the CSA to close itself down either...
 
EXTERNAL CONNECTORS
      * inboxes : inboxes=["datain","inbox"]
      * outboxes=["outbox"]
 
"""
 
import sys
 
from Axon.Component import component, scheduler, linkage, newComponent
from Axon.Ipc import producerFinished, errorInformation
from Kamaelia.ReadFileAdaptor import ReadFileAdaptor
from Kamaelia.SimpleServerComponent import SimpleServer
from Kamaelia.MimeRequestComponent import mimeObject, MimeRequestComponent
from Kamaelia.requestLine import BadRequest
from Kamaelia.Util.ToStringComponent import ToStringComponent
 
crashAndBurn = { "error404" : False }
 
class HTTPServer(component):
   Inboxes=["inbox","_frommime", "_errmon", "_fromfile", "_sigfromfile"]# List of inbox names if different
   Outboxes=["outbox","_pass","signal"]# List of outbox names if different
   def __init__(self, debug=0):
      super(HTTPServer, self).__init__()
      self.debug = debug
 
   def initialiseComponent(self):
      self.mimehandler = MimeRequestComponent()
      self.httphandler = HTTPReqestHandler()
#      toString = ToStringComponent()
#      myDataSource = ReadFileAdaptor(command="afortune.pl",
#                              readmode="bitrate",
#                              bitrate=95200, chunkrate=25)
      assert self.debugger.note("HTTPServer.initialiseComponent", 1, "Initialising HTTPServer protocol handler ", self.__class__)
#      self.link(        source=(self,"inbox"),
#               sink=(mimehandler,"inbox"),
#               passthrough=2)
      self.link(  source=(self,"_pass"),
                  sink=(self.mimehandler,"inbox"))
#      self.link(  source=(mimehandler,"outbox"),
#                  sink=(toString,"inbox"))
      self.link(  source=(self.mimehandler,"outbox"),
                  sink=(self.httphandler,"inbox"))
      self.link(  source=(self.httphandler,"outbox"),
                  sink=(self,"_frommime"))
      self.link(  source=(self.mimehandler,"signal"),
                  sink=(self,"_errmon"))
#      self.link(	source=(toString,"outbox"),
#              sink=(self,"outbox"),
#               passthrough=1)
      self.addChildren(self.mimehandler, self.httphandler)
 
      return newComponent( self.mimehandler, self.httphandler )#, toString ] )
 
   def mainBody(self):
      """All the interesting work has been done by linking the file reader's output
      to our output"""
      if self.dataReady("_fromfile"):
         temp = self.recv("_fromfile")
         self.send(temp)
         return 1
      if self.dataReady("_sigfromfile"):
         temp = self.recv("_sigfromfile")
         self.send(temp,"signal")
      if self.dataReady("inbox"):
         temp = self.recv("inbox")
         self.send(temp,"_pass")
      if self.dataReady("_frommime"):
         filename = self.recv("_frommime")
         try:
            file = open(filename, 'r')
            close(file)
         except Exception, e:
            msg = 'HTTP/1.0 404 "Not Found\n\n"'
            self.send(msg)
            self.send(producerFinished(self), "signal")
            if crashAndBurn["error404"]:
               raise e
            return 0
         msg ='HTTP/1.0 200 "OK\n\n"'
         self.send(msg)
         self.rfa = ReadFileAdapter(filename=filename, readmode="bitrate")
         self.link(source=(self.rfa, "outbox"),
                     sink=(self, "_fromfile"))
         self.link(source=(self.rfa, "signal"),
                     sink=(self, "_sigfromfile"))
         self.addChildren(self.rfa)
#         self.send(str(theData), "outbox")
#         sig = producerFinished(self)
#         self.send(sig, "signal")
         return [self.rfa]
      if self.dataReady("_errmon"):
         temp = self.recv("_errmon")
         if isinstance(temp, errorInformation):
            if isinstance(temp.exception, BadRequest):
               msg = 'HTTP/1.0 400 "Bad Request"\n'
               self.send(msg)
            sig = producerFinished(self)
            self.send(sig,"signal")
            return 0
      return 1
 
   def closeDownComponent(self):
      """Simple subcomponent killer."""
      for child in self.childComponents():
         self.removeChild(child)
      self.mimehandler=None
      self.httphandler=None
      self.rfa=None
#      self.toString=None
 
class HTTPReqestHandler(component):
   def __init__(self, debug=0):
      super(HTTPReqestHandler).__init__()
      self.debug = debug
 
   def mainBody(self):
      if self.dataReady("inbox"):
         reqdata = self.recv("inbox")
         filename = reqdata.preambleLine.url
         if filename[0] is '/':
            filename = filename[1:]
         self.send(filename)
      return 1
 
#   404str = 'HTTP/1.0 404 Not Found\nContent-type: text/html\nContent-length: 143\n\n<HTML>\n<TITLE> Not Found </TITLE>\n<BODY BGCOLOR="#FFFFFF">\n<FONT FACE="Arial,Helvetica,Geneva" SIZE=-1>\n<H2> Not Found </H2>\n</BODY>\n</HTML>\n\n'
 
 
 
 
if __name__ == '__main__':
   SimpleServer(protocol=HTTPServer, port=8082).activate()
   scheduler.run.runThreads(slowmo=0)