Skip to content

Commit 25eb1e7

Browse files
committed
ci_build/: Re-design build-logs webpage
The newly created webpage combines the previous two webpages- info.txt and log/index.html. This web-page combines the results of both the pages and shows them in a better UI/UX with additional features of filtering and searching within the existing logs. The logs are fetched from a JSON file which is created from the logs stored in the log file _site/community.log
1 parent 323e60f commit 25eb1e7

13 files changed

+328
-58
lines changed

.moban.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ packages:
99
- gci
1010
- gsoc
1111
- gamification
12-
- log
12+
- ci_build
1313
- meta_review
1414
- model
1515
- twitter

.nocover.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ nocover_file_globs:
88
- community/git.py
99
- gci/*.py
1010
- gsoc/*.py
11-
- log/*.py
11+
- ci_build/*.py
1212
- meta_review/handler.py
1313
- model/*.py
1414
- openhub/*.py

ci_build/view_log.py

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import re
2+
import json
3+
import os
4+
from django.views.generic import TemplateView
5+
6+
from community.views import get_header_and_footer
7+
from community.git import (get_org_name,
8+
get_owner,
9+
get_deploy_url,
10+
get_upstream_deploy_url)
11+
12+
13+
class BuildLogsView(TemplateView):
14+
template_name = 'build_logs.html'
15+
16+
def get_build_info(self):
17+
data = {
18+
'Org name': get_org_name(),
19+
'Owner': get_owner(),
20+
'Deploy URL': get_deploy_url(),
21+
}
22+
try:
23+
upstream_deploy_url = get_upstream_deploy_url()
24+
data['Upstream deploy URL'] = upstream_deploy_url
25+
except RuntimeError:
26+
data['Upstream deploy URL'] = 'Not found'
27+
return dict(data)
28+
29+
def get_build_logs(self):
30+
log_lines = []
31+
log_level_specific_lines = {
32+
'INFO': [],
33+
'DEBUG': [],
34+
'WARNING': [],
35+
'ERROR': [],
36+
'CRITICAL': []
37+
}
38+
log_file_path = './_site/community.log'
39+
log_file_exists = os.path.isfile(log_file_path)
40+
if log_file_exists:
41+
with open(log_file_path) as log_file:
42+
previous_found_level = None
43+
for line in log_file:
44+
log_lines.append(line)
45+
levels = re.findall(r'\[[A-Z]+]', line)
46+
if levels:
47+
level = levels[0]
48+
level = previous_found_level = level[1:-1]
49+
log_level_specific_lines[level].append(line)
50+
elif previous_found_level:
51+
log_level_specific_lines[previous_found_level].append(
52+
line)
53+
with open('./_site/ci-build-detailed-logs.json',
54+
'w+') as build_logs_file:
55+
data = {
56+
'logs': log_lines,
57+
'logs_level_Specific': log_level_specific_lines
58+
}
59+
json.dump(data, build_logs_file, indent=4)
60+
return True
61+
else:
62+
return False
63+
64+
def get_context_data(self, **kwargs):
65+
context = super().get_context_data(**kwargs)
66+
context = get_header_and_footer(context)
67+
context['build_info'] = self.get_build_info()
68+
context['build_logs_stored'] = self.get_build_logs()
69+
return context

community/urls.py

+5-11
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
from django.conf.urls.static import static
77
from django.conf import settings
88

9-
from community.views import HomePageView, info
9+
from community.views import HomePageView
1010
from gci.views import index as gci_index
1111
from gci.feeds import LatestTasksFeed as gci_tasks_rss
1212
from twitter.view_twitter import index as twitter_index
13-
from log.view_log import index as log_index
13+
from ci_build.view_log import BuildLogsView
1414
from data.views import index as contributors_index
1515
from gamification.views import index as gamification_index
1616
from meta_review.views import index as meta_review_index
@@ -79,12 +79,6 @@ def get_organization():
7979
distill_func=get_index,
8080
distill_file='index.html',
8181
),
82-
distill_url(
83-
'info.txt', info,
84-
name='index',
85-
distill_func=get_index,
86-
distill_file='info.txt',
87-
),
8882
distill_url(
8983
r'gci/tasks/rss.xml', gci_tasks_rss(),
9084
name='gci-tasks-rss',
@@ -104,10 +98,10 @@ def get_organization():
10498
distill_file='twitter/index.html',
10599
),
106100
distill_url(
107-
r'log/', log_index,
108-
name='log',
101+
r'CI/Build/', BuildLogsView.as_view(),
102+
name='ci_build',
109103
distill_func=get_index,
110-
distill_file='log/index.html',
104+
distill_file='CI/Build/index.html',
111105
),
112106
distill_url(
113107
r'contributors/$', contributors_index,

community/views.py

-21
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
1-
from django.http import HttpResponse
21
from django.views.generic.base import TemplateView
32

43
from trav import Travis
54

65
from .git import (
7-
get_deploy_url,
86
get_org_name,
9-
get_owner,
10-
get_upstream_deploy_url,
117
get_remote_url
128
)
139
from data.models import Team, Contributor
@@ -110,20 +106,3 @@ def get_context_data(self, **kwargs):
110106
context['top_gamification_users'] = self.get_top_gamification_users(
111107
count=5)
112108
return context
113-
114-
115-
def info(request):
116-
data = {
117-
'Org name': get_org_name(),
118-
'Owner': get_owner(),
119-
'Deploy URL': get_deploy_url(),
120-
}
121-
try:
122-
upstream_deploy_url = get_upstream_deploy_url()
123-
data['Upstream deploy URL'] = upstream_deploy_url
124-
except RuntimeError:
125-
data['Upstream deploy URL'] = 'Not found'
126-
127-
s = '\n'.join(name + ': ' + value
128-
for name, value in data.items())
129-
return HttpResponse(s)

log/view_log.py

-12
This file was deleted.

setup.cfg

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ testpaths =
1414
gci
1515
gsoc
1616
gamification
17-
log
17+
ci_build
1818
meta_review
1919
model
2020
twitter
@@ -70,7 +70,7 @@ source =
7070
gci
7171
gsoc
7272
gamification
73-
log
73+
ci_build
7474
meta_review
7575
model
7676
twitter
@@ -82,7 +82,7 @@ omit =
8282
community/git.py
8383
gci/*.py
8484
gsoc/*.py
85-
log/*.py
85+
ci_build/*.py
8686
meta_review/handler.py
8787
model/*.py
8888
openhub/*.py

static/css/build_logs.css

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
.build-info-section section,
2+
.build-logs-section section {
3+
min-width: 300px;
4+
width: 80%;
5+
}
6+
7+
.build-information,
8+
.build-logs {
9+
background-color: black;
10+
padding-left: 10px;
11+
font-weight: bold;
12+
color: white;
13+
}
14+
15+
.build-information p {
16+
font-size: 1.5em;
17+
margin: 0;
18+
}
19+
20+
.build-logs {
21+
max-height: 900px;
22+
overflow: scroll;
23+
overflow-x: hidden;
24+
}
25+
26+
.build-logs p {
27+
margin: 0;
28+
}
29+
30+
.build-logs-section .log-chooser {
31+
max-width: 200px;
32+
min-width: 150px;
33+
border-radius: 100px;
34+
box-shadow: 0px 0px 25px 2px black;
35+
color: #454343;
36+
background-color: #c7da99;
37+
padding-left: 10px;
38+
}
39+
40+
.build-logs-section .search-field {
41+
max-width: 500px;
42+
min-width: 300px;
43+
border-radius: 100px;
44+
box-shadow: 0px 0px 25px 2px black;
45+
color: #454343;
46+
background-color: #edf5af;
47+
padding: 0px 20px;
48+
flex-flow: row;
49+
}
50+
51+
.build-logs-section input[type='search']:focus:not(.browser-default) {
52+
background-color: #edf5af;
53+
border-radius: 100px;
54+
font-size: medium;
55+
}
56+
57+
.main-content h3 {
58+
color: #37474f;
59+
}
60+
61+
.section-header {
62+
display: flex;
63+
align-items: center;
64+
}
65+
66+
.section-header form {
67+
display: flex;
68+
justify-content: space-around;
69+
flex-direction: row;
70+
flex-grow: 3;
71+
}
72+
73+
@media only screen and (max-width: 768px) {
74+
.build-logs-section .search-field {
75+
display: none;
76+
}
77+
}
78+
79+
.webpage-name {
80+
width: 100%;
81+
}

static/css/index.css

-7
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,6 @@
9797
background-color: #ee8940;
9898
}
9999

100-
.apply-flex-center {
101-
display: flex;
102-
justify-content: center;
103-
flex-flow: row wrap;
104-
align-items: center;
105-
}
106-
107100
.organization_map {
108101
text-align: center;
109102
padding: 2% 0%;

static/css/main.css

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
.apply-flex-center {
2+
display: flex;
3+
justify-content: center;
4+
flex-flow: row wrap;
5+
align-items: center;
6+
}
7+
18
body {
29
font-family: 'Ubuntu Mono', monospace;
310
background-color: #edf5af;

static/js/build_logs.js

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
$(document).ready(function(){
2+
$('select').formSelect();
3+
4+
var log_chooser_input = $('#log-chooser-input');
5+
var search_input = $('#search');
6+
var log_type = null;
7+
var logs_data = null;
8+
var searched_keyword = '';
9+
10+
function addLogsHTML(info){
11+
var info_el = $('<p></p>').text(info);
12+
$('.build-logs').append(info_el);
13+
}
14+
15+
function updateBuildLogsHTML(){
16+
$('.build-logs p').remove();
17+
if (logs_data.length < 37){
18+
$('.build-logs').css('overflow-y', 'hidden');
19+
}
20+
if(logs_data.length > 0) {
21+
for(var entry in logs_data){
22+
if(logs_data[entry]){
23+
addLogsHTML(logs_data[entry]);
24+
}
25+
}
26+
}
27+
else {
28+
var info = 'There are no log entries for tag ' + log_type + '.';
29+
addLogsHTML(info);
30+
}
31+
}
32+
33+
function updateBuildLogs(type){
34+
$.getJSON("/static/ci-build-detailed-logs.json", function(data) {
35+
log_type = type;
36+
if(log_type === 'logs') {
37+
logs_data = data[log_type];
38+
}
39+
else {
40+
logs_data = data.logs_level_Specific[log_type];
41+
}
42+
updateBuildLogsHTML();
43+
})
44+
.fail(function(data, textStatus, error) {
45+
var err = "Request Failed: " + textStatus + ", " + error;
46+
console.error( err);
47+
});
48+
}
49+
50+
function searchBuildLogs(){
51+
var found = false;
52+
var info = '';
53+
for(var entry in logs_data){
54+
if(logs_data[entry]){
55+
info = logs_data[entry];
56+
if(info.includes(searched_keyword)){
57+
found = true;
58+
addLogsHTML(info);
59+
}
60+
}
61+
}
62+
if(!found){
63+
if(log_type === 'logs'){
64+
info = searched_keyword + ' not found in logs!';
65+
}
66+
else {
67+
info = searched_keyword + ' not found in ' + log_type +
68+
' level logs!';
69+
}
70+
addLogsHTML(info);
71+
}
72+
}
73+
74+
updateBuildLogs('logs');
75+
76+
log_chooser_input.on('change', function(){
77+
updateBuildLogs(log_chooser_input.val());
78+
});
79+
80+
search_input.on('keypress', function(key){
81+
if(key.which === 13){
82+
searched_keyword = search_input.val();
83+
$('.build-logs p').remove();
84+
searchBuildLogs();
85+
}
86+
});
87+
88+
});

0 commit comments

Comments
 (0)