This is really getting to be a bane for me.  After a while I'll get
the following traceback:

Page handler: <bound method Root.search of <archive.controllers.Root
object at 0x00FAE2F0>>
Traceback (most recent call last):
  File 
"c:\python24\lib\site-packages\cherrypy-2.2.0beta-py2.4.egg\cherrypy\_cphttptools.py",
line 98, in _run
    self.main()
  File 
"c:\python24\lib\site-packages\cherrypy-2.2.0beta-py2.4.egg\cherrypy\_cphttptools.py",
line 246, in main
    body = page_handler(*virtual_path, **self.params)
  File "c:\svn\turbogears\turbogears\controllers.py", line 240, in newfunc
    html, fragment, *args, **kw)
  File "c:\svn\turbogears\turbogears\database.py", line 189, in
run_with_transaction
    retval = func(*args, **kw)
  File "c:\svn\turbogears\turbogears\controllers.py", line 262, in _execute_func
    return _process_output(tg_format, output, html, fragment)
  File "c:\svn\turbogears\turbogears\controllers.py", line 62, in
_process_output
    output = view.render(output, tg_format, template=template,fragment=fragment)
  File "c:\svn\turbogears\turbogears\view.py", line 57, in render
    return engine.render(info, format, fragment, template)
  File 
"c:\python24\lib\site-packages\TurboKid-0.9.0-py2.4.egg\turbokid\kidsupport.py",
line 136, in render
    return t.serialize(encoding=self.defaultencoding, output=format,
fragment=fragment)
  File "c:\python24\lib\site-packages\kid-0.9a0-py2.4.egg\kid\__init__.py",
line 236, in serialize
    return serializer.serialize(self, encoding, fragment)
  File "c:\python24\lib\site-packages\kid-0.9a0-py2.4.egg\kid\serialization.py",
line 51, in serialize
    text = list(self.generate(stream, encoding, fragment))
  File "c:\python24\lib\site-packages\kid-0.9a0-py2.4.egg\kid\serialization.py",
line 324, in generate
    stream = iter(stream)
  File "c:\python24\lib\site-packages\kid-0.9a0-py2.4.egg\kid\__init__.py",
line 261, in __iter__
    return iter(self.transform())
  File "c:\python24\lib\site-packages\kid-0.9a0-py2.4.egg\kid\__init__.py",
line 316, in transform
    stream = self.pull()
  File "c:\python24\lib\site-packages\kid-0.9a0-py2.4.egg\kid\__init__.py",
line 275, in pull
    self.initialize()
  File "C:\svn\mailarc\frontend\trunk\archive\templates\search.py",
line 20, in initialize
  File "C:\svn\mailarc\frontend\trunk\archive\templates\master.py",
line 20, in initialize
TypeError: 'NoneType' object is not callable

The strange thing is, this happens only on *one* of my templates.  The
other 2 which are currently accessible work without a problem.  I have
attached my controller, and the templates of the app in question
because I've been trying to track this issue down for a few days.  If
anyone needs further info, please just ask.

I will continue to hunt, but I am having to put it on the backburner
to get the rest of the app finished in time.

Thanks in advance,

Lee
import turbogears
from turbogears import controllers, widgets, validators
from model import Message, Recipient, Person, Attachment, Body, Unknown
from datetime import datetime
from sqlobject import NOT, AND, OR, SQLObjectNotFound
import cherrypy
from turbogears import jsonify
import myforms


def size_suffix(value):
    suffix = ["B", "KB", "MB", "GB"]
    i = 0
    while value > 1024:
        value = value/1024
        i += 1
    return suffix[i]


class AttachmentController(controllers.Controller):

    @turbogears.expose()
    def default(self, *vpath, **params):
        if not vpath:
            return self.index(**params)
        # Make a copy of vpath in a list
        vpath = list(vpath)
        atom = vpath.pop(0)

        # See if the first virtual path member is a container action
        method = getattr(self, atom, None)
        if method and getattr(method, "exposed"):
            return method(*vpath, **params)

        # Not a container action; the URI atom must be an existing ID
        # Coerce the ID to the correct db type
        try:
            id = int(atom)
            att = Attachment.get(id)
        except SQLObjectNotFound, ValueError:
            raise cherrypy.NotFound

        # There may be further virtual path components.
        # Try to map them to methods in this class.
        if vpath:
            method = getattr(self, vpath[0], None)
            if method and getattr(method, "exposed"):
                return method(message=message, id=id, *vpath[1:], **params)
            else:
                raise cherrypy.NotFound

        # No further known vpath components. Call a default handler.
        return self.download(att=att, id=id, *vpath, **params)
        
    @turbogears.expose()
    def download(self, att=None, id=None, *args, **kw):
        """Downloads the attachment for the given NewsPost id"""
        from StringIO import StringIO #This is for streaming from the DB
        import urllib
        
        referer = cherrypy.request.headerMap.get('Referer', '/')
        
        if att or id:
            if not att:
                try:
                    att = Attachment.get(id)
                except SQLObjectNotFound:
                    raise cherrypy.NotFound
                    
            cherrypy.response.headerMap["Content-Type"] = att.filetype
            cherrypy.response.headerMap["Content-Disposition"] = 
"attachment;filename=%s" % urllib.quote(att.filename)
            return cherrypy.lib.cptools.fileGenerator(StringIO(att.data))
        else:
            raise cherrypy.NotFound
    
    
class PeopleController(controllers.Controller):
    @turbogears.expose(template="archive.templates.people")
    def index(self):
        
        uands = 
Person.select(Person.q.email.endswith("@uands.com")).orderBy("name")
        other = 
Person.select(NOT(Person.q.email.endswith("@uands.com"))).orderBy("name")
        people = {"uands": uands, "other": other}
        
        return dict(people=people, order=["uands","other"])
    
class MessageController(controllers.Controller):
    @turbogears.expose(template="archive.templates.messages.index")
    def index(self):
        
        defective = Message.select(NOT(Message.q.defects == None))
        unknowns = Message.select(Unknown.q.messageID == Message.q.id)
        bodynotdecoded = Message.select(AND(Body.q.messageID == Message.q.id, 
Body.q.decoded == False))
        attnotdecoded = Message.select("""message.id = 
attachment_message.message_id 
                                        AND attachment.id = 
attachment_message.attachment_id
                                        AND NOT attachment.decoded = 1""",
                                        clauseTables=['attachment_message', 
'attachment'])
                                        
        return dict(defective=defective,
                    unknowns=unknowns,
                    bodynotdecoded=bodynotdecoded,
                    attnotdecoded=attnotdecoded)
                    
    @turbogears.expose(template="archive.templates.messages.view", 
validators=dict(id=validators.Int()))
    def view(self, id=None, message=None, *args, **kw):
        
        if message or id:
            if message:
                pass
            elif id:
                try:
                    message = Message.get(id)
                except SQLObjectNotFound:
                    raise cherrypy.NotFound
            
            return dict(message=message, forwardform=myforms.forwardform)
        else:
            # We've fallen through.  Throw a notfound
            raise cherrypy.NotFound
    
    @turbogears.expose()
    def body(self, id=None, message=None, *args, **kw):
        
        if id or message:
            if not message:
                try:
                    id = int(id)
                    message = Message.get(id)
                except SQLObjectNotFound, ValueError:
                    raise cherrypy.NotFound
            if message.htmlbody:
                return message.htmlbody
            else:
                from docutils.core import publish_parts
                return publish_parts(message.plainbody, 
writer_name="html")["html_body"]
                
        
        raise cherrypy.NotFound
    
    @turbogears.expose()
    def headers(self, id=None, message=None, *args, **kw):
        
        if id or message:
            if not message:
                try:
                    id = int(id)
                    message = Message.get(id)
                except SQLObjectNotFound, ValueError:
                    raise cherrypy.NotFound
                
            cherrypy.response.headerMap["Content-Type"] = "text/plain"
            return message.headers
            
        else:
            raise cherrypy.NotFound
            
    
    @turbogears.expose(inputform=myforms.forwardform)
    def forward(self, id=None, message=None, fwd_msgid=None, forward_to=None, 
*args, **kw):
        
        if cherrypy.request.form_errors:
            return self.index()
            
        referer = cherrypy.request.headerMap.get('Referer', "/")
        
        if id is None or message is None:
            raise cherrypy.NotFound
        else:
            if not message:
                try:
                    id = int(id)
                    message = Message.get(id)
                except SQLObjectNotFound, ValueError:
                    raise cherrypy.NotFound
                    
            import string
            
            template = {}
            template['plain'] = """
=== Archived Message ID: %(msgid)s ===

From: %(sender)s
To: %(to)s
CC: %(cc)s
Date Sent: %(sent)s

%(message)s

=== End of Archived Message ===

Message: http://localhost:8080/messages/%(msgid)s
Original Headers: http://localhost:8080/messages/%(msgid)s/headers
"""

            template['html'] = """
<div class="archivemessagemeta">
=== Archived Message ID: %(msgid)s ===<br/>
    From: %(sender)s<br/>
    To: %(to)s<br/>
    CC: %(cc)s<br/>
    Date Sent: %(sent)s<br/>
    <br/>
    <div class="archivemessage">
    %(message)s
    </div>
=== End of Archived Message ===<br/>
<a href="http://localhost:8080/messages/%(msgid)s">View message</a><br/>
<a href="http://localhost:8080/messages/%(msgid)s/headers">View original 
headers</a>
</div>
"""
    
            
            template_data = {"msgid": str(message.id),
                            "sender": "%s <%s>" % (message.sender.name or "", 
message.sender.email),
                            "to": ", ".join(["%s <%s>" % (recip.name or "", 
recip.email) for recip in message.recipients if recip.type == "to"]),
                            "cc": ", ".join(["%s <%s>" % (recip.name or "", 
recip.email) for recip in message.recipients if recip.type == "cc"]),
                            "sent": message.messagedate.ctime(),
                            "message": None}
            
            
            import email.Message
            import email.Utils
            import quopri
            import cStringIO
            import base64
            import smtplib
            
            emsg = email.Message.Message()
            emsg["To"] = forward_to
            emsg["From"] = "[EMAIL PROTECTED]"
            emsg["Subject"] = "ARCHIVE: %s" % message.subject
            emsg["Date"] = email.Utils.formatdate(localtime=1)
            emsg["Message-ID"] = email.Utils.make_msgid()
            emsg["Mime-version"] = "1.0"
            emsg["Content-type"] = "Multipart/mixed"
            emsg.preamble = "Mime message\n"
            emsg.epilogue = ""
            
            for body in message.bodies:
                submsg = email.Message.Message()
                submsg["Content-type"] = "text/%s" % body.type
                submsg["Content-transfer-encoding"] = body.encoding or "7bit"
                template_data["message"] = body.body
                unencoded = cStringIO.StringIO(template[body.type] % 
template_data)
                encoded = cStringIO.StringIO()
                
                if "quoted-printable" == body.encoding and body.decoded:
                    quopri.encode(unencoded, encoded, 1)
                else:
                    encoded = unencoded
                    
                submsg.set_payload(encoded.getvalue())
                emsg.attach(submsg)
                
                encoded.close()
                unencoded.close()
                
            for att in message.attachments:
                submsg = email.Message.Message()
                submsg.add_header("Content-type", att.filetype, 
name=att.filename)
                unencoded = cStringIO.StringIO(att.data)
                encoded = cStringIO.StringIO()
                cte = None
                
                if "quoted-printable" == att.encoding and body.decoded:
                    quopri.encode(unencoded, encoded, 1)
                    cte = att.encoding
                elif "base64" == att.encoding and body.decoded:
                    base64.encode(unencoded, encoded)
                    cte = att.encoding
                else:
                    encoded = unencoded
                    cte = "7bit"
                    
                submsg.add_header("Content-transfer-encoding", cte)
                submsg.set_payload(encoded.getvalue())
                emsg.attach(submsg)
                
                encoded.close()
                unencoded.close()
                
            server = smtplib.SMTP("192.168.1.101")
            result = server.sendmail('[EMAIL PROTECTED]', forward_to, 
emsg.as_string())
            server.quit()
            
            if len(result) > 0:
                error = "%s: %s" % (result[forward_to][0], 
result[forward_to][1])
                turbogears.flash("The message could not be forwarded. [%s]" % 
error)
            else:
                turbogears.flash("The message was forwarded successfully.")
                
            raise cherrypy.HTTPRedirect(referer)
        
    
    @turbogears.expose()
    def default(self, *vpath, **params):
        if not vpath:
            return self.index(**params)
        # Make a copy of vpath in a list
        vpath = list(vpath)
        atom = vpath.pop(0)

        # See if the first virtual path member is a container action
        method = getattr(self, atom, None)
        if method and getattr(method, "exposed"):
            return method(*vpath, **params)

        # Not a container action; the URI atom must be an existing ID
        # Coerce the ID to the correct db type
        try:
            id = int(atom)
            message = Message.get(id)
        except SQLObjectNotFound, ValueError:
            raise cherrypy.NotFound

        # There may be further virtual path components.
        # Try to map them to methods in this class.
        if vpath:
            method = getattr(self, vpath[0], None)
            if method and getattr(method, "exposed"):
                return method(message=message, id=id, *vpath[1:], **params)
            else:
                raise cherrypy.NotFound

        # No further known vpath components. Call a default handler.
        return self.view(message=message, id=id, *vpath, **params)


class Root(controllers.RootController):
    
    messages = MessageController()
    people = PeopleController()
    attachments = AttachmentController()
    
    @turbogears.expose(template="archive.templates.index")
    def index(self):
        now = datetime.now()
        today = datetime(now.year, now.month, now.day)
        
        total = Message.select().count()
        daytotal = Message.select(Message.q.archivedate >= today).count()
                        
        #search_fields = widgets.Fieldset(widgets=search_widgets, 
legend="Search Criteria")
        
        return dict(total=total,
                    daytotal=daytotal,
                    searchform=myforms.searchform)
        
    @turbogears.expose(allow_json=True)
    def contactsearch(self, searchString=None, *args, **kw):
        resultlist = []
        if searchString and searchString.strip() != "":
            possibles = 
Person.select(OR(Person.q.name.startswith(searchString), 
Person.q.email.startswith(searchString)), orderBy=Person.q.name)
            if possibles.count() > 0:
                resultlist = [p.name or p.email for p in possibles]
            
        return dict(textItems=resultlist)
        
    @turbogears.expose(html="archive.templates.search", 
inputform=myforms.searchform)
    def search(self, contact_to, contact_from, subject, start_date, end_date):
        from sqlobject.sqlbuilder import Alias, CONTAINSSTRING
        if cherrypy.request.form_errors:
            return self.index()
        
        rPerson = Alias(Person, "rperson")
        
        # Add the joins first
        criteria = [Message.q.senderID == Person.q.id, 
                    Message.q.id == Recipient.q.messageID,
                    rPerson.q.id == Recipient.q.personID]
        
        if contact_from:
            criteria.append(OR(Person.q.name == contact_from, Person.q.email == 
contact_from))
        if contact_to:
            criteria.append(OR(rPerson.q.name == contact_to, rPerson.q.email == 
contact_to))
        if subject:
            criteria.append(CONTAINSSTRING(Message.q.subject, subject))
        if start_date:
            criteria.append(Message.q.messagedate >= start_date)
        if end_date:
            criteria.append(Message.q.messagedate <= end_date)
            
        results = Message.select(AND(*criteria), 
distinct=True).orderBy(-Message.q.messagedate)
        
        input_values = dict(contact_to=contact_to,
                contact_from=contact_from,
                subject=subject,
                start_date=start_date,
                end_date=end_date)
                
        return dict(input_values=input_values,
                searchform=myforms.searchform,
                results=results)
        

Attachment: master.kid
Description: Binary data

Attachment: index.kid
Description: Binary data

Attachment: people.kid
Description: Binary data

Attachment: search.kid
Description: Binary data

Reply via email to