Merge branch 'feature-run-query' into dev

This commit is contained in:
Troy Dai 2018-05-15 14:55:00 -07:00
Родитель 4439115930 870d7e5eb6
Коммит 00a6b47483
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 9608535492BEDAC8
9 изменённых файлов: 201 добавлений и 80 удалений

Просмотреть файл

@ -1,7 +1,9 @@
import logging
import os
import datetime
import re
import requests
from flask import Flask, render_template, redirect, url_for, request, session
from flask_login import LoginManager, login_required, login_user, logout_user
@ -77,9 +79,13 @@ def runs():
page = int(request.args.get('page', 1))
query = Run.query.order_by(Run.creation.desc()).offset(page_size * (page - 1)).limit(20)
return render_template('runs.html', runs=query, page=page,
previous_page=url_for('runs', page=max(page - 1, 1)),
next_page=url_for('runs', page=page + 1))
page_previous = url_for('runs', page=page - 1) if page > 1 else None
page_next = url_for('runs', page=page + 1)
return render_template('runs.html', runs=query,
page=page,
page_previous=page_previous,
page_next=page_next)
@app.route('/run/<int:run_id>')
@ -89,10 +95,24 @@ def run(run_id: int):
if not this_run:
return 404
show_log = request.args.get('logs', 'False') == 'true'
query = request.args.get('query', '')
tasks = [t for t in this_run.tasks if t.result != 'Passed']
if query:
tasks = [t for t in tasks if re.search(query, t.identifier)]
logs = dict()
if show_log:
for t in tasks:
resp = requests.get(t.log_path)
if resp.status_code < 300:
logs[t.id] = resp.text
tasks = sorted(tasks, key=lambda t: t.name)
return render_template('run.html', tasks=tasks)
return render_template('run.html', tasks=tasks, logs=logs, query=query)
@app.route('/help', methods=['GET'])

Просмотреть файл

@ -1,10 +1,11 @@
# pylint: disable=unused-import, too-few-public-methods
import json
from flask_sqlalchemy import SQLAlchemy
from .user import User
db = SQLAlchemy() # pylint: disable=invalid-name
@ -62,3 +63,29 @@ class Task(db.Model):
# relationship
run_id = db.Column(db.Integer, db.ForeignKey('run.id'), nullable=False)
run = db.relationship('Run', backref=db.backref('tasks', cascade='all, delete-orphan', lazy=True))
def __init__(self, *args, **kwargs):
super(Task, self).__init__(*args, **kwargs)
self._settings = None
@property
def identifier(self) -> str:
return self.settings_in_json['classifier']['identifier'] # pylint: disable=unsubscriptable-object
@property
def log_path(self) -> str:
return self.result_in_json['a01.reserved.tasklogpath'] # pylint: disable=unsubscriptable-object
@property
def settings_in_json(self) -> dict:
if not hasattr(self, '_settings'):
setattr(self, '_settings', json.loads(self.settings))
return getattr(self, '_settings')
@property
def result_in_json(self) -> dict:
if not hasattr(self, '_result'):
setattr(self, '_result', json.loads(self.result_details))
return getattr(self, '_result')

Просмотреть файл

@ -11,4 +11,12 @@ main {
table.condense {
font-family: 'Roboto', sans-serif;
font-size: small;
}
pre code {
font-size: 0.5rem;
}
div.log {
background-color: beige;
}

Просмотреть файл

@ -1,7 +1,7 @@
{% extends "layout.html" %}
{% block body %}
<div>
<a class="waves-effect waves-light btn-large" href="{{ url_for('runs') }}">Runs</a>
<div class="jumbotron">
<h1 class="display-4">Welcome to the A01 Automation Dashboard.</h1>
</div>
{% endblock %}

Просмотреть файл

@ -3,37 +3,59 @@
<head>
{% block head %}
<meta charset="UTF-8">
<title>A01 Automation</title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css"
integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB"
crossorigin="anonymous">
<link rel="stylesheet"
href="{{ url_for('static', filename='styles/main.css') }}">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/css/materialize.min.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/js/materialize.min.js"></script>
<title>A01 Automation</title>
{% endblock %}
</head>
<body>
<nav>
<div class="nav-wrapper container">
<a href="/" class="brand-logo">A01 Automation</a>
<ul class="right">
{% if current_user.is_authenticated %}
<li><a href="{{ url_for('profile') }}">{{ current_user.user_name }}</a></li>
{% else %}
<a href="{{ url_for('login') }}">Log in</a>
{% endif %}
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="#">A01 Automation</a>
<div class="collapse navbar-collapse">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="{{ url_for('runs') }}">Runs</a>
</li>
</ul>
<ul class="navbar-nav">
<li class="nav-item">
{% if current_user.is_authenticated %}
<a class="nav-link" href="{{ url_for('profile') }}">{{ current_user.user_name }}</a>
{% else %}
<a class="nav-link" href="{{ url_for('login') }}">Log in</a>
{% endif %}
</li>
</ul>
</div>
</nav>
<div class="container">
{% if current_user.is_authenticated %}
{% block body %}
{% endblock %}
{% else %}
<p class="lead">You are not authenticated. Please use the log in link in the upper right of the page to navigate
to the log in page.</p>
<p class="lead">This page may redirect to the log in page, automatically in 3 seconds.</p>
{% endif %}
</div>
{% if current_user.is_authenticated %}
{% block body %}
{% endblock %}
{% else %}
<div class="container">
<div class="jumbotron">
<h1 class="display-4">Please log in.</h1>
<p class="lead">You are not authenticated. Please use the log in link in the upper right of the page to
navigate to the log in page.</p>
<hr class="my-4">
<p class="lead">This page may redirect to the log in page automatically in 10 seconds.</p>
</div>
</div>
{% endif %}
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"
integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"
integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T"
crossorigin="anonymous"></script>
</body>
</html>

Просмотреть файл

@ -1,5 +1,5 @@
{% extends "layout.html" %}
{% block head %}
{{ super() }}
<meta http-equiv="refresh" content="3;{{ auth_link }}"/>
<meta http-equiv="refresh" content="10;{{ auth_link }}"/>
{% endblock %}

Просмотреть файл

@ -1,29 +1,63 @@
{% extends "layout.html" %}
{% block body %}
<p class="lead center-align">Only failures are shown</p>
<table class="condense">
<thead>
</thead>
<tbody>
<tr>
<th>ID</th>
<th>Name</th>
<th>Status</th>
</tr>
{% for task in tasks %}
<tr>
<td> {{ task.id }} </td>
<td style="overflow: hidden; white-space: nowrap; text-overflow: ellipsis; max-width: 40rem"> {{ task.name }} </td>
<td> {{ task.result }} </td>
</tr>
{% endfor %}
</tbody>
</table>
{# <div class="center-align">#}
{# <ul class="pagination">#}
{# <li><a href="{{ previous_page }}"><i class="material-icons">chevron_left</i></a></li>#}
{# <li class="active"><a href="#!">{{ page }}</a></li>#}
{# <li><a href="{{ next_page }}"><i class="material-icons">chevron_right</i></a></li>#}
{# </ul>#}
{# </div>#}
<div class="container-fluid">
<div class="row">
<form class="mt-1 ml-1 col-12" method="get">
<div class="form-row">
<div class="col">
<label class="sr-only" for="query">Query</label>
<input type="text" class="form-control mb-2 mr-sm-2"
id="query" name="query"
placeholder="Current query: {{ query or 'Empty' }}.">
</div>
<div class="col-auto mt-1 mb-2 mr-sm-2">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="inlineFormCheck" name="logs"
value="true">
<label class="form-check-label" for="inlineFormCheck">
Logs
</label>
</div>
</div>
<div class="col-auto">
<button type="submit" class="btn btn btn-primary mb-2">Submit</button>
</div>
</div>
</form>
</div>
<div class="row">
<table class="table table-sm table-hover ml-1 mb-1 mr-1">
<thead>
<tr>
<th>ID</th>
<th>Identifier</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{% for task in tasks %}
<tr>
<td>{{ task.id }}</td>
<td style="overflow: hidden; white-space: nowrap; text-overflow: ellipsis; max-width: 40rem">
{{ task.identifier }}
</td>
<td>{{ task.result }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="row mt-5">
{% for t in tasks %}
{% if t.id in logs %}
<div class="col ml-1 mt-1">
<p class="lead">{{ t.identifier }}</p>
<div class="log">
<pre><code>{{ logs[t.id] }}</code></pre>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
{% endblock %}

Просмотреть файл

@ -1,28 +1,36 @@
{% extends "layout.html" %}
{% block body %}
<table class="condense">
<thead>
</thead>
<tbody>
<tr>
<th>ID</th>
<th>Name</th>
<th>Status</th>
</tr>
{% for run in runs %}
<div class="container-fluid">
<table class="table table-hover table-sm">
<thead>
<tr>
<td><a href="{{ url_for('run', run_id=run.id) }}">{{ run.id }}</a></td>
<td>{{ run.name }}</td>
<td>{{ run.status }}</td>
<th>ID</th>
<th>Name</th>
<th>Status</th>
</tr>
{% endfor %}
</tbody>
</table>
<div class="center-align">
<ul class="pagination">
<li><a href="{{ previous_page }}"><i class="material-icons">chevron_left</i></a></li>
<li class="active"><a href="#!">{{ page }}</a></li>
<li><a href="{{ next_page }}"><i class="material-icons">chevron_right</i></a></li>
</ul>
</thead>
<tbody>
{% for run in runs %}
<tr>
<td><a href="{{ url_for('run', run_id=run.id) }}">{{ run.id }}</a></td>
<td>{{ run.name }}</td>
<td>{{ run.status }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div>
<nav>
<ul class="pagination justify-content-center">
{% if page_previous %}
<li class="page-item"><a class="page-link" href="{{ page_previous }}">Previous</a></li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#" tabindex="-1">Previous</a></li>
{% endif %}
<li class="page-item"><a class="page-link" href="#">{{ page }}</a></li>
<li class="page-item"><a class="page-link" href="{{ page_next }}">Next</a></li>
</ul>
</nav>
</div>
</div>
{% endblock %}

Просмотреть файл

@ -1,5 +1,7 @@
pip>=10.0.0
requests==2.18.4
flask==1.0.2
flask-login==0.4.1
flask-sqlalchemy==2.3.1