Commits

Ben Bangert committed f340448

Added traceback saving and handling

  • Participants
  • Parent commits b61e3a1

Comments (0)

Files changed (5)

kai/controllers/tracebacks.py

 import logging
 
+from paste.script.util.uuid import uuid4
 from pylons import request, response, session, tmpl_context as c
 from pylons.controllers.util import abort, redirect_to
+from pylons.decorators import jsonify
 
 from kai.lib.base import BaseController, render
-#from kai import model
+from kai.model import Traceback
 
 log = logging.getLogger(__name__)
 
 class TracebacksController(BaseController):
-
-    def index(self):
-        # Return a rendered template
-        #   return render('/template.mako')
-        # or, Return a response
-        return 'Hello World'
+    @jsonify
+    def create(self):
+        """Create a new traceback in the system, pegged to the current
+        user ID and session ID"""
+        tb = Traceback.from_xml(request.body)
+        tb.uuid = uuid4()
+        tb.store(self.db)
+        result = {}
+        uuid = tb.uuid
+        result['traceback'] = dict(link=tb.id, uuid=uuid)
+        return result
+    
+    def reown(self, id):
+        if 'uuid' not in request.GET:
+            abort(500)
+        tb = Traceback.load(self.db, id) or abort(404)
+        session.save()
+        tb.session_id = session.id
+        if c.user:
+            tb.displayname = c.user.displayname
+            tb.human_id = c.user.id
+        tb.uuid = None
+        tb.store(self.db)
+        return 'ok'

kai/model/__init__.py

 from kai.model.human import Human
 from kai.model.paste import Paste
 from kai.model.snippet import Snippet
+from kai.model.traceback import Traceback

kai/model/traceback.py

+from datetime import datetime
+
+import pylons
+from couchdb.schema import DateTimeField, DictField, Document, TextField, \
+    ListField, FloatField, Schema, IntegerField, BooleanField, View
+
+class Traceback(Document):
+    type = TextField(default='Traceback')
+    human_id = TextField()
+    displayname = TextField()
+    uuid = TextField()
+    session_id = TextField()
+    created = DateTimeField(default=datetime.utcnow)    
+    description = TextField()
+    
+    # Meta
+    language = TextField()
+    version = TextField()
+    full_version = TextField()
+    platform = TextField()
+    libraries = ListField(DictField(Schema.build(
+        name = TextField(),
+        version = TextField()
+    )))
+    
+    # Traceback stack / Exception
+    frames = ListField(DictField(Schema.build(
+        module = TextField(),
+        line = IntegerField(),
+        function = TextField(),
+        operation = TextField()
+    )))
+    exception_type = TextField()
+    exception_value = TextField()
+    
+    by_uuid = View('traceback', '''
+        function(doc) {
+          if (doc.type == 'Traceback' && doc.uuid) {
+            emit(doc.uuid, null);
+          }
+        }''', include_docs=True)
+    
+    by_time = View('traceback', '''
+        function(doc) {
+          if (doc.type == 'Traceback') {
+            emit(doc.created, null);
+          }
+        }''', include_docs=True)
+    
+    @classmethod
+    def from_xml(cls, content):
+        try:
+            from lxml import objectify
+        except ImportError:
+            return False
+        
+        data = objectify.fromstring(content)
+        tb = cls()
+        
+        # Add the session id if available, otherwise force a new session
+        if not pylons.session.id:
+            pylons.session.save()
+        tb.session_id = pylons.session.id
+        
+        exc = data.exception
+        tb.exception_type = exc.type.text
+        tb.exception_value = exc.value.text
+        
+        # Add the meta data
+        sysinfo = data.sysinfo
+        tb.language = sysinfo.language.text
+        tb.version = sysinfo.language.get('version')
+        tb.full_version = sysinfo.language.get('full_version')
+        
+        tb.libraries = []
+        for lib in sysinfo.libraries.iterchildren(tag='library'):
+            tb.libraries.append(dict(name=lib.get('name'),
+                                version=lib.get('version')))
+        
+        tb.frames = []
+        for frame in data.stack.iterchildren(tag='frame'):
+            fd = dict(module=frame.module.text, line=int(frame.line.text),
+                      function=frame.function.text)
+            if hasattr(frame, 'operation'):
+                fd['operation'] = frame.operation.text
+            else:
+                fd['operation'] = 'No operation context'
+            tb.frames.append(fd)
+        return tb

kai/templates/buildbot/index.mako

     
     <p>${_("""In <a href="http://www.selenic.com/mercurial/">Mercurial</a>, the revision
         control system (RCS) used by Pylons, the latest revision is called the
-        tip.""")}</p>
+        tip.""") | n}</p>
     
     <h2>${_('Latest Release  (%s)' % app_globals.current_version)}</h2>
     ${build_table(c.releases)}
 import pylons
 
 from kai.config.environment import load_environment
-from kai.model import Article, Documentation, Human, Paste, Rating, Snippet
+from kai.model import Article, Documentation, Human, Paste, Rating, Snippet, Traceback
 
 log = logging.getLogger(__name__)
 
         Snippet.by_date, Snippet.by_author, Snippet.by_slug, Snippet.by_title,
         Snippet.by_author_id, Snippet.by_tag, Snippet.all_tags,
         Snippet.author_totals,
+        
+        Traceback.by_uuid, Traceback.by_time,
     ])