kai / 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)
    
    by_session_id = View('traceback', '''
        function(doc) {
          if (doc.type == 'Traceback' && doc.session_id) {
            emit(doc.session_id, 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
    
    def is_owner(self, user, check_session=False):
        if user and self.human_id and user.id == self.human_id:
            return True
        else:
            if check_session:
                if pylons.session.id and self.session_id and pylons.session.id == self.session_id:
                    return True
            return False
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.