Log reporting
This commit is contained in:
1 parent
3a4c191b11
commit
c2eb50a7ee
2 files changed
+270
-31
No files matched your search
@@ -43,6 +43,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.page.log .nav li.hint {
|
||||||
|
text-align: center;
|
||||||
|
width: 400px;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -200px;
|
||||||
|
font-style: italic;
|
||||||
|
font-size: 11px;
|
||||||
|
position: absolute;
|
||||||
|
right: 20px;
|
||||||
|
opacity: .5;
|
||||||
|
bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.page.log .loading {
|
.page.log .loading {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
@@ -65,11 +78,18 @@
|
|||||||
.page.log .container .time {
|
.page.log .container .time {
|
||||||
clear: both;
|
clear: both;
|
||||||
color: lightgrey;
|
color: lightgrey;
|
||||||
padding: 3px 0;
|
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
border-top: 1px solid rgba(255, 255, 255, 0.2);
|
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
.page.log .container .time.highlight {
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
.page.log .container .time span {
|
||||||
|
padding: 5px 0 3px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
.page.log [data-filter=INFO] .error,
|
.page.log [data-filter=INFO] .error,
|
||||||
.page.log [data-filter=INFO] .debug,
|
.page.log [data-filter=INFO] .debug,
|
||||||
@@ -91,5 +111,69 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.page.log .container .error { color: #FFA4A4; }
|
.page.log .container .error { color: #FFA4A4; }
|
||||||
.page.log .container .debug { opacity: .4; }
|
.page.log .container .debug span { opacity: .4; }
|
||||||
|
|
||||||
|
.do_report {
|
||||||
|
position: absolute;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page.log .report {
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0,0,0,.7);
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 99999;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: OpenSans,"Helvetica Neue",Helvetica,Arial,Geneva,sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page.log .report .button {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 10px 0;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page.log .report .bug {
|
||||||
|
width: 800px;
|
||||||
|
height: 80%;
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
margin: 0 0 0 -400px;
|
||||||
|
transform: translate(0, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page.log .report .bug textarea {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
background: #FFF;
|
||||||
|
padding: 20px;
|
||||||
|
overflow: auto;
|
||||||
|
color: #666;
|
||||||
|
height: 70%;
|
||||||
|
font-family: Lucida Console, Monaco, Nimbus Mono L, monospace, serif;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page.log .container ::-webkit-selection {
|
||||||
|
background-color: #000;
|
||||||
|
color: #FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page.log .container ::-moz-selection {
|
||||||
|
background-color: #000;
|
||||||
|
color: #FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page.log .container ::-ms-selection {
|
||||||
|
background-color: #000;
|
||||||
|
color: #FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page.log .container ::selection {
|
||||||
|
background-color: #000;
|
||||||
|
color: #FFF;
|
||||||
|
}
|
||||||
@@ -7,34 +7,54 @@ Page.Log = new Class({
|
|||||||
title: 'Show recent logs.',
|
title: 'Show recent logs.',
|
||||||
has_tab: false,
|
has_tab: false,
|
||||||
|
|
||||||
indexAction: function(){
|
report_text: '\
|
||||||
|
### Steps to reproduce:\n\
|
||||||
|
1. ..\n\
|
||||||
|
2. ..\n\
|
||||||
|
\n\
|
||||||
|
### Information:\n\
|
||||||
|
Movie(s) I have this with: ...\n\
|
||||||
|
Quality of the movie being searched: ...\n\
|
||||||
|
Providers I use: ...\n\
|
||||||
|
Version of CouchPotato: ...\n\
|
||||||
|
Running on: ...\n\
|
||||||
|
\n\
|
||||||
|
### Logs:\n\
|
||||||
|
```\n{issue}```',
|
||||||
|
|
||||||
|
indexAction: function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.getLogs(0);
|
self.getLogs(0);
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getLogs: function(nr){
|
getLogs: function (nr) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if(self.log) self.log.destroy();
|
if (self.log) self.log.destroy();
|
||||||
self.log = new Element('div.container.loading', {
|
self.log = new Element('div.container.loading', {
|
||||||
'text': 'loading...'
|
'text': 'loading...',
|
||||||
|
'events': {
|
||||||
|
'mouseup:relay(.time)': function(e){
|
||||||
|
self.showSelectionButton.delay(100, self, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}).inject(self.el);
|
}).inject(self.el);
|
||||||
|
|
||||||
Api.request('logging.get', {
|
Api.request('logging.get', {
|
||||||
'data': {
|
'data': {
|
||||||
'nr': nr
|
'nr': nr
|
||||||
},
|
},
|
||||||
'onComplete': function(json){
|
'onComplete': function (json) {
|
||||||
self.log.set('text', '');
|
self.log.set('text', '');
|
||||||
self.log.adopt(self.createLogElements(json.log));
|
self.log.adopt(self.createLogElements(json.log));
|
||||||
self.log.removeClass('loading');
|
self.log.removeClass('loading');
|
||||||
|
|
||||||
var nav = new Element('ul.nav', {
|
var nav = new Element('ul.nav', {
|
||||||
'events': {
|
'events': {
|
||||||
'click:relay(li.select)': function(e, el){
|
'click:relay(li.select)': function (e, el) {
|
||||||
self.getLogs(parseInt(el.get('text'))-1);
|
self.getLogs(parseInt(el.get('text')) - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -43,7 +63,7 @@ Page.Log = new Class({
|
|||||||
new Element('li.filter').grab(
|
new Element('li.filter').grab(
|
||||||
new Element('select', {
|
new Element('select', {
|
||||||
'events': {
|
'events': {
|
||||||
'change': function(){
|
'change': function () {
|
||||||
var type_filter = this.getSelected()[0].get('value');
|
var type_filter = this.getSelected()[0].get('value');
|
||||||
self.log.set('data-filter', type_filter);
|
self.log.set('data-filter', type_filter);
|
||||||
self.scrollToBottom();
|
self.scrollToBottom();
|
||||||
@@ -60,8 +80,8 @@ Page.Log = new Class({
|
|||||||
// Selections
|
// Selections
|
||||||
for (var i = 0; i <= json.total; i++) {
|
for (var i = 0; i <= json.total; i++) {
|
||||||
new Element('li', {
|
new Element('li', {
|
||||||
'text': i+1,
|
'text': i + 1,
|
||||||
'class': 'select ' + (nr == i ? 'active': '')
|
'class': 'select ' + (nr == i ? 'active' : '')
|
||||||
}).inject(nav);
|
}).inject(nav);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,9 +89,9 @@ Page.Log = new Class({
|
|||||||
new Element('li.clear', {
|
new Element('li.clear', {
|
||||||
'text': 'clear',
|
'text': 'clear',
|
||||||
'events': {
|
'events': {
|
||||||
'click': function(){
|
'click': function () {
|
||||||
Api.request('logging.clear', {
|
Api.request('logging.clear', {
|
||||||
'onComplete': function(){
|
'onComplete': function () {
|
||||||
self.getLogs(0);
|
self.getLogs(0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -80,6 +100,11 @@ Page.Log = new Class({
|
|||||||
}
|
}
|
||||||
}).inject(nav);
|
}).inject(nav);
|
||||||
|
|
||||||
|
// Hint
|
||||||
|
new Element('li.hint', {
|
||||||
|
'text': 'Select multiple lines & report an issue'
|
||||||
|
}).inject(nav);
|
||||||
|
|
||||||
// Add to page
|
// Add to page
|
||||||
nav.inject(self.log, 'top');
|
nav.inject(self.log, 'top');
|
||||||
|
|
||||||
@@ -89,29 +114,159 @@ Page.Log = new Class({
|
|||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
createLogElements: function(logs){
|
createLogElements: function (logs) {
|
||||||
|
|
||||||
var elements = [];
|
var elements = [];
|
||||||
|
|
||||||
logs.each(function(log){
|
logs.each(function (log) {
|
||||||
elements.include(new Element('div', {
|
elements.include(new Element('div', {
|
||||||
'class': 'time ' + log.type.toLowerCase(),
|
'class': 'time ' + log.type.toLowerCase()
|
||||||
'text': log.time
|
}).adopt(
|
||||||
}).adopt(
|
new Element('span', {
|
||||||
new Element('span.type', {
|
'text': log.time
|
||||||
'text': log.type
|
}),
|
||||||
}),
|
new Element('span.type', {
|
||||||
new Element('span.message', {
|
'text': log.type
|
||||||
'text': log.message
|
}),
|
||||||
})
|
new Element('span.message', {
|
||||||
))
|
'text': log.message
|
||||||
});
|
})
|
||||||
|
))
|
||||||
|
});
|
||||||
|
|
||||||
return elements;
|
return elements;
|
||||||
},
|
},
|
||||||
|
|
||||||
scrollToBottom: function(){
|
scrollToBottom: function () {
|
||||||
new Fx.Scroll(window, {'duration': 0}).toBottom();
|
new Fx.Scroll(window, {'duration': 0}).toBottom();
|
||||||
|
},
|
||||||
|
|
||||||
|
showSelectionButton: function(e){
|
||||||
|
var self = this,
|
||||||
|
selection = self.getSelected(),
|
||||||
|
start_node = selection.anchorNode,
|
||||||
|
parent_start = start_node.parentNode.getParent('.time'),
|
||||||
|
end_node = selection.focusNode.parentNode.getParent('.time'),
|
||||||
|
text = '';
|
||||||
|
|
||||||
|
var remove_button = function(){
|
||||||
|
self.log.getElements('.highlight').removeClass('highlight');
|
||||||
|
if(self.do_report)
|
||||||
|
self.do_report.destroy();
|
||||||
|
document.body.removeEvent('click', remove_button);
|
||||||
|
};
|
||||||
|
remove_button();
|
||||||
|
|
||||||
|
if(parent_start)
|
||||||
|
start_node = parent_start;
|
||||||
|
|
||||||
|
var nodes = [start_node],
|
||||||
|
current_node = start_node;
|
||||||
|
|
||||||
|
while(current_node != end_node){
|
||||||
|
current_node = current_node.getNext('.time');
|
||||||
|
nodes.include(current_node);
|
||||||
|
}
|
||||||
|
nodes.each(function(node, nr){
|
||||||
|
node.addClass('highlight');
|
||||||
|
node.getElements('span').each(function(span){
|
||||||
|
text += self.spaceFill(span.get('text') + ' ', 6);
|
||||||
|
});
|
||||||
|
text += '\n';
|
||||||
|
});
|
||||||
|
|
||||||
|
self.do_report = new Element('a.do_report.button', {
|
||||||
|
'text': 'Report issue',
|
||||||
|
'styles': {
|
||||||
|
'top': e.page.y,
|
||||||
|
'left': e.page.x
|
||||||
|
},
|
||||||
|
'events': {
|
||||||
|
'click': function(e){
|
||||||
|
(e).stop();
|
||||||
|
|
||||||
|
self.showReport(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).inject(document.body);
|
||||||
|
|
||||||
|
setTimeout(function(){
|
||||||
|
document.body.addEvent('click', remove_button);
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
showReport: function(text){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var overlay = new Element('div.report', {
|
||||||
|
'method': 'post',
|
||||||
|
'events': {
|
||||||
|
'click': function(e){
|
||||||
|
overlay.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).grab(
|
||||||
|
new Element('div.bug', {
|
||||||
|
'events': {
|
||||||
|
'click': function(e){
|
||||||
|
(e).stopPropagation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).adopt(
|
||||||
|
new Element('h1', {
|
||||||
|
'text': 'Report a bug'
|
||||||
|
}),
|
||||||
|
new Element('span').adopt(
|
||||||
|
new Element('span', {
|
||||||
|
'text': 'Read '
|
||||||
|
}),
|
||||||
|
new Element('a.button', {
|
||||||
|
'target': '_blank',
|
||||||
|
'text': 'the contributing guide',
|
||||||
|
'href': 'https://github.com/RuudBurger/CouchPotatoServer/blob/develop/contributing.md'
|
||||||
|
}),
|
||||||
|
new Element('span', {
|
||||||
|
'text': ' before posting, then copy the text below'
|
||||||
|
})
|
||||||
|
),
|
||||||
|
new Element('textarea', {
|
||||||
|
'text': self.report_text.replace('{issue}', text),
|
||||||
|
'events': {
|
||||||
|
'click': function(){
|
||||||
|
this.select();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
new Element('a.button', {
|
||||||
|
'target': '_blank',
|
||||||
|
'text': 'Create a new issue on GitHub with the text above',
|
||||||
|
'href': 'https://github.com/RuudBurger/CouchPotatoServer/issues/new?body=Paste the text here'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
overlay.inject(self.log);
|
||||||
|
},
|
||||||
|
|
||||||
|
getSelected: function(){
|
||||||
|
if (window.getSelection)
|
||||||
|
return window.getSelection();
|
||||||
|
else if (document.getSelection)
|
||||||
|
return document.getSelection();
|
||||||
|
else {
|
||||||
|
var selection = document.selection && document.selection.createRange();
|
||||||
|
if (selection.text)
|
||||||
|
return selection.text;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
spaceFill: function( number, width ){
|
||||||
|
if ( number.toString().length >= width )
|
||||||
|
return number;
|
||||||
|
return ( new Array( width ).join( ' ' ) + number.toString() ).substr( -width );
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
Reference in new issue
Block a user