PageRenderTime 82ms CodeModel.GetById 40ms app.highlight 13ms RepoModel.GetById 27ms app.codeStats 0ms

/kai/model/traceback.py

https://bitbucket.org/bbangert/kai/
Python | 130 lines | 122 code | 6 blank | 2 comment | 0 complexity | f70a73e0d3fe21785a8b6c5122e0601a MD5 | raw file
  1from datetime import datetime
  2
  3import pylons
  4from couchdb.schema import DateTimeField, DictField, Document, TextField, \
  5    ListField, FloatField, Schema, IntegerField, BooleanField, View
  6
  7from kai.model.generics import Comment
  8
  9class Traceback(Document):
 10    type = TextField(default='Traceback')
 11    human_id = TextField()
 12    displayname = TextField()
 13    email = TextField()
 14    uuid = TextField()
 15    session_id = TextField()
 16    created = DateTimeField(default=datetime.utcnow)    
 17    description = TextField()
 18    
 19    # Meta
 20    language = TextField()
 21    version = TextField()
 22    full_version = TextField()
 23    platform = TextField()
 24    libraries = ListField(DictField(Schema.build(
 25        name = TextField(),
 26        version = TextField()
 27    )))
 28    
 29    # Traceback stack / Exception
 30    frames = ListField(DictField(Schema.build(
 31        module = TextField(),
 32        line = IntegerField(),
 33        function = TextField(),
 34        operation = TextField()
 35    )))
 36    exception_type = TextField()
 37    exception_value = TextField()
 38    
 39    by_uuid = View('traceback', '''
 40        function(doc) {
 41          if (doc.type == 'Traceback' && doc.uuid) {
 42            emit(doc.uuid, null);
 43          }
 44        }''', include_docs=True)
 45    
 46    by_time = View('traceback', '''
 47        function(doc) {
 48          if (doc.type == 'Traceback') {
 49            emit(doc.created, null);
 50          }
 51        }''', include_docs=True)
 52    
 53    by_session_id = View('traceback', '''
 54        function(doc) {
 55          if (doc.type == 'Traceback' && doc.session_id) {
 56            emit(doc.session_id, null);
 57          }
 58        }''', include_docs=True)
 59    
 60    @classmethod
 61    def from_xml(cls, content):
 62        try:
 63            from lxml import objectify
 64        except ImportError:
 65            return False
 66        
 67        data = objectify.fromstring(content)
 68        tb = cls()
 69        
 70        # Add the session id if available, otherwise force a new session
 71        if not pylons.session.id:
 72            pylons.session.save()
 73        tb.session_id = pylons.session.id
 74        
 75        exc = data.exception
 76        tb.exception_type = exc.type.text
 77        tb.exception_value = exc.value.text
 78        
 79        # Add the meta data
 80        sysinfo = data.sysinfo
 81        tb.language = sysinfo.language.text
 82        tb.version = sysinfo.language.get('version')
 83        tb.full_version = sysinfo.language.get('full_version')
 84        
 85        tb.libraries = []
 86        for lib in sysinfo.libraries.iterchildren(tag='library'):
 87            tb.libraries.append(dict(name=lib.get('name'),
 88                                version=lib.get('version')))
 89        
 90        tb.frames = []
 91        for frame in data.stack.iterchildren(tag='frame'):
 92            fd = dict(module=frame.module.text, line=int(frame.line.text),
 93                      function=frame.function.text)
 94            if hasattr(frame, 'operation'):
 95                fd['operation'] = frame.operation.text
 96            else:
 97                fd['operation'] = 'No operation context'
 98            tb.frames.append(fd)
 99        return tb
100    
101    def is_owner(self, user, check_session=False):
102        if user and self.human_id and user.id == self.human_id:
103            return True
104        else:
105            if check_session:
106                if pylons.session.id and self.session_id and pylons.session.id == self.session_id:
107                    return True
108            return False
109    
110    def comment_count(self):
111        comments = Comment.comment_count(pylons.tmpl_context.db)[self.id]
112        if not comments:
113            return 0
114        else:
115            return comments[0]
116    
117    @classmethod
118    def associate_tracebacks(cls, user):
119        db = pylons.tmpl_context.db
120        tracebacks = list(cls.by_session_id(db)[pylons.session.id])
121        if tracebacks:
122            for tb in tracebacks:
123                try:
124                    tb.session_id = None
125                    tb.human_id = user.id
126                    tb.displayname = user.displayname
127                    tb.email = user.email
128                    tb.store(db)
129                except:
130                    pass