Added gui htmlpy code, todo.txt - maintain it

This commit is contained in:
2015-12-18 23:28:01 +05:30
parent 5d8e96543e
commit 1e85848702
7 changed files with 253 additions and 0 deletions
View File
@@ -0,0 +1,78 @@
import htmlPy
from utils import render_template
import os
import redis
import dateutil.parser
from datetime import datetime
import humanfriendly
import os.path
env_redis_port = os.environ.get("pytest_status_port")
if env_redis_port:
REDIS_PORT = int(env_redis_port)
else:
REDIS_PORT = 5946
class Controller(htmlPy.Object):
# GUI callable functions have to be inside a class.
# The class should be inherited from htmlPy.Object.
dict_state_desc = {
"start": "Starting Tests",
"collect": "Collecting Tests",
"runtest": "Running Tests",
"end": "Finished Tests"
}
def __init__(self, app_gui):
super(Controller, self).__init__()
self.i = 0
self.app_gui = app_gui
self.last_state = None
# Initialize the class here, if required.
@htmlPy.Slot()
def redraw(self):
# from main import app as app_gui
print(self.app_gui.dir_name)
redis_db = redis.StrictRedis(host='localhost', port=REDIS_PORT, db=0)
# make sure that this is correct redis db
try:
assert redis_db.get("PYTEST_STATUS_DB") == "1"
except AssertionError, e:
print("Got redis db, but it is not related to pytest status")
raise e
dir_name = self.app_gui.dir_name
hash_dir_name = redis_db.hget("directories_to_hash", dir_name)
if hash_dir_name is None:
raise Exception("dir_name = {dir_name} not found in redis db".format(
dir_name=dir_name))
dict_state = {}
dict_state["dir_name"] = dir_name
dict_state["dir_name_topfolder"] = os.path.basename(dir_name)
dict_state["state"] = redis_db.get("{hash_a}_state".format(hash_a=hash_dir_name))
dict_state["state_desc"] = self.dict_state_desc[dict_state["state"]]
dict_state["last_updated"] = redis_db.get("{hash_a}_last_updated".format(hash_a=hash_dir_name))
dict_state["last_updated_obj"] = dateutil.parser.parse(dict_state["last_updated"])
last_updated_rel = (datetime.now() - dict_state["last_updated_obj"]).seconds # in seconds
if last_updated_rel > 60:
# when >1 min, reolve only upto min
last_updated_rel = last_updated_rel - (last_updated_rel % 60)
dict_state["last_updated_friendly"] = humanfriendly.format_timespan(last_updated_rel)
dict_state["collect"] = redis_db.lrange("{hash_a}_collect".format(hash_a=hash_dir_name), 0, -1)
dict_state["pass"] = redis_db.lrange("{hash_a}_pass".format(hash_a=hash_dir_name), 0, -1)
dict_state["fail"] = redis_db.lrange("{hash_a}_fail".format(hash_a=hash_dir_name), 0, -1)
dict_state["skip"] = redis_db.lrange("{hash_a}_skip".format(hash_a=hash_dir_name), 0, -1)
if (not self.last_state) or (self.last_state != dict_state):
print("called redraw")
self.app_gui.html = render_template(self.app_gui, "index.html", dict_state)
self.last_state = dict_state
@@ -0,0 +1,44 @@
import htmlPy
import os
import sys
from PyQt4.QtGui import QApplication
import PyQt4.QtCore as QtCore
# Import back-end functionalities
from gui_backend import Controller
if len(sys.argv) > 1:
dir_name_raw = sys.argv[1]
else:
dir_name_raw = "."
dir_name = os.path.abspath(dir_name_raw)
# GUI initializations
app = htmlPy.AppGUI(title=u"{dir_name} - Test Status".format(dir_name=dir_name),
developer_mode=True, width=150, height=80)
app.window.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
screen_geo = QApplication.desktop().availableGeometry()
screen_topright = screen_geo.topRight()
app.x_pos = (screen_topright.x() - 20) - app.width
app.y_pos = (screen_topright.y() + 20)
# import pdb;pdb.set_trace()
# GUI configarg
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
app.static_path = os.path.join(BASE_DIR, "static/")
app.template_path = os.path.join(BASE_DIR, "tmpl/")
app.dir_name = dir_name
# Register back-end functionalities
app_backend = Controller(app)
app.bind(app_backend)
# GUI render config
# app.html = u""
app_backend.redraw()
# Start application
if __name__ == "__main__":
app.start()
@@ -0,0 +1,109 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{dir_name}}</title>
<style>
*
{
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body
{
margin: 2px;
padding: 0;
}
.last-test-statusviz
{
width: 100%;
height: 1.5em;
}
.statusdot
{
height: 100%;
{% if collect|length > 0 %}
width: {{100/(collect|length)}}%;
{% else %}
width: 0;
{% endif %}
/*width: 1em;*/
padding: 1px;
float: left;
}
.statusdot-fill
{
width: 100%;
height: 100%;
}
.fill-pass
{
background-color: green;
}
.fill-fail
{
background-color: red;
}
.last-test-statusviz
{
overflow: hidden;
border: 2px solid black;
}
.last-test-timerelative
{
font-size: 0.75em;
height: 1em;
/*overflow: hidden;*/
}
.last-test-dirname
{
font-size: 0.75em;
/*height: 1em;*/
/*position: relative;*/
}
/*.last-test-dirname-redacted
{
position: absolute;
top: 0;
right: 0;
width: 999px;
font-size: 0.75em;
text-align: right;
}*/
</style>
<!-- <script type="text/javascript" src="./refresh.js"></script> -->
<script type="text/javascript">
// debugger
document.onload = setInterval(function(){Controller.redraw()},1000)
</script>
</head>
<body>
<div class="section-last-test">
<div class="state">
{{ state_desc }}
</div>
<div class="last-test-statusviz">
{% for testname in collect %}
<div class="statusdot statusdot-{{loop.index0}}">
<!-- {{ testname }} -->
{% if testname in pass %}
<div class="statusdot-fill fill-pass"></div>
{% elif testname in fail %}
<div class="statusdot-fill fill-fail"></div>
{% endif %}
</div>
{% endfor %}
</div>
<div class="last-test-timerelative">
Got {{ last_updated_friendly }} ago
</div>
<div class="last-test-dirname">
Folder : {{ dir_name_topfolder }}
<!-- <div class="last-test-dirname-redacted"> -->
<!-- </div> -->
</div>
</div>
</body>
</html>
@@ -0,0 +1 @@
setTimeout(Controller.redraw, 500)
+13
View File
@@ -0,0 +1,13 @@
Todo
------
1. move rendering update to js using diff-dom + nunjucks ( to be decided )
2. (-done manually, add tests)check intermediate test steps like collect, testrun
3. In plugin, set attributes in chunk using pipeline, using `with`
Done
------
1. (---) Get dirname from cmdline
2. (---) responsive width of test
3. (---) Time should update automatically
+8
View File
@@ -0,0 +1,8 @@
import jinja2
import os
def render_template(app, tmpl_name, tmpl_params):
with open(os.path.join(app.template_path, tmpl_name)) as f_tmpl:
tmpl_content = f_tmpl.read()
return jinja2.Template(tmpl_content).render(tmpl_params)