2019-05-14 19:00:38 +02:00
|
|
|
from datetime import datetime
|
2018-01-29 19:53:51 +01:00
|
|
|
from flask import render_template, make_response, Blueprint
|
2018-01-29 03:39:04 +01:00
|
|
|
from .models.pr import PullRequest
|
2020-11-12 15:35:02 +01:00
|
|
|
from .models.appcatalog import App
|
2018-11-07 20:12:36 +01:00
|
|
|
from .models.appci import AppCI, AppCIBranch
|
2018-05-30 02:52:58 +02:00
|
|
|
from .models.unlistedapps import UnlistedApp
|
2017-12-19 19:20:27 +01:00
|
|
|
from .settings import SITE_ROOT
|
2018-05-22 23:51:23 +02:00
|
|
|
import json
|
2020-11-05 22:23:31 +01:00
|
|
|
import os
|
2017-12-19 19:20:27 +01:00
|
|
|
|
|
|
|
main = Blueprint('main', __name__, url_prefix=SITE_ROOT)
|
2017-12-19 17:03:51 +01:00
|
|
|
|
|
|
|
|
|
|
|
def sort_test_results(results):
|
|
|
|
|
|
|
|
results = list(results)
|
|
|
|
|
|
|
|
for r in results:
|
|
|
|
r.level = -1 if r.level is None else r.level
|
|
|
|
|
|
|
|
return sorted(results,
|
2017-12-19 19:20:27 +01:00
|
|
|
key=lambda r: (-r.level, -r.score(), r.app.name))
|
|
|
|
|
2017-12-19 17:03:51 +01:00
|
|
|
|
2017-12-19 19:20:27 +01:00
|
|
|
@main.route('/')
|
2017-12-19 17:03:51 +01:00
|
|
|
def index():
|
|
|
|
return render_template('index.html')
|
|
|
|
|
2018-01-29 03:39:04 +01:00
|
|
|
@main.route('/pullrequests')
|
|
|
|
def pullrequests():
|
|
|
|
|
|
|
|
prs = PullRequest.query.all()
|
|
|
|
|
|
|
|
prs = sorted(prs, key=lambda pr: (pr.review_priority, pr.created), reverse=True)
|
|
|
|
|
|
|
|
active_prs = [ pr for pr in prs if pr.review_priority >= 0]
|
|
|
|
count_by_team = { "all": len(active_prs),
|
|
|
|
"core": len([pr for pr in active_prs if pr.repo.team == "core"]),
|
|
|
|
"apps": len([pr for pr in active_prs if pr.repo.team == "apps"]),
|
|
|
|
"infra": len([pr for pr in active_prs if pr.repo.team == "infra"]),
|
|
|
|
"doc": len([pr for pr in active_prs if pr.repo.team == "doc"]) }
|
|
|
|
|
|
|
|
return render_template("pullrequests.html", prs=prs, count_by_team=count_by_team)
|
|
|
|
|
2018-05-30 02:31:02 +02:00
|
|
|
#
|
|
|
|
# Apps CI
|
|
|
|
#
|
|
|
|
|
2018-01-29 03:39:04 +01:00
|
|
|
|
2017-12-19 19:20:27 +01:00
|
|
|
@main.route('/appci/branch/<branch>')
|
2017-12-19 17:03:51 +01:00
|
|
|
def appci_branch(branch):
|
|
|
|
|
|
|
|
branch = AppCIBranch.query.filter_by(name=branch).first_or_404()
|
|
|
|
|
|
|
|
app_results = sort_test_results(branch.most_recent_tests_per_app())
|
|
|
|
|
2020-09-03 19:33:59 +02:00
|
|
|
tests = AppCI.tests.copy()
|
2020-11-13 01:46:54 +01:00
|
|
|
if "Malfurmed path" in tests:
|
2020-11-05 22:23:31 +01:00
|
|
|
tests.remove("Malformed path")
|
2020-09-03 19:33:59 +02:00
|
|
|
|
|
|
|
return render_template("appci_branch.html", tests=tests,
|
2017-12-19 17:03:51 +01:00
|
|
|
branch=branch,
|
|
|
|
app_results=app_results)
|
|
|
|
|
2017-12-19 19:20:27 +01:00
|
|
|
|
|
|
|
@main.route('/appci/app/<app>')
|
2017-12-19 17:03:51 +01:00
|
|
|
def appci_app(app):
|
|
|
|
|
|
|
|
app = App.query.filter_by(name=app).first_or_404()
|
|
|
|
|
|
|
|
branch_results = list(app.most_recent_tests_per_branch())
|
|
|
|
|
|
|
|
for r in branch_results:
|
2019-07-20 20:16:05 +02:00
|
|
|
r.level = -1 if r.level in ["?", None] else int(r.level)
|
2017-12-19 17:03:51 +01:00
|
|
|
|
2020-09-03 19:33:59 +02:00
|
|
|
tests = AppCI.tests.copy()
|
|
|
|
if "Malformed path" in tests:
|
2020-11-05 22:23:31 +01:00
|
|
|
tests.remove("Malformed path")
|
|
|
|
|
2020-11-05 23:06:25 +01:00
|
|
|
history_file = "./app/scripts/appListsHistory/per_app/history_%s.json" % app.name
|
2020-11-05 22:23:31 +01:00
|
|
|
if os.path.exists(history_file):
|
2020-11-05 23:06:25 +01:00
|
|
|
history = json.loads(open(history_file).read())
|
2020-11-05 22:23:31 +01:00
|
|
|
else:
|
|
|
|
history = []
|
|
|
|
|
2020-09-03 19:33:59 +02:00
|
|
|
return render_template("appci_app.html", tests=tests,
|
2017-12-19 17:03:51 +01:00
|
|
|
app=app,
|
2020-11-05 22:23:31 +01:00
|
|
|
branch_results=branch_results,
|
|
|
|
history=history)
|
2017-12-19 17:03:51 +01:00
|
|
|
|
2017-12-19 19:20:27 +01:00
|
|
|
|
|
|
|
@main.route('/appci/compare/<ref>...<target>')
|
2017-12-19 17:03:51 +01:00
|
|
|
def appci_compare(ref, target):
|
|
|
|
|
|
|
|
assert ref != target, "Can't compare the same branches, bruh"
|
|
|
|
|
|
|
|
ref = AppCIBranch.query.filter_by(name=ref).first_or_404()
|
|
|
|
target = AppCIBranch.query.filter_by(name=target).first_or_404()
|
|
|
|
|
|
|
|
ref_results = sort_test_results(ref.most_recent_tests_per_app())
|
|
|
|
target_results = sort_test_results(target.most_recent_tests_per_app())
|
|
|
|
|
|
|
|
for ref_r in ref_results:
|
|
|
|
ref_r.level_compare = next((r.level for r in target_results
|
|
|
|
if r.app == ref_r.app),
|
|
|
|
-1)
|
2018-01-30 22:20:23 +01:00
|
|
|
if ref_r.level == -1 or ref_r.level_compare == -1:
|
|
|
|
ref_r.compare = "unknown"
|
|
|
|
elif ref_r.level == ref_r.level_compare:
|
|
|
|
ref_r.compare = "same"
|
|
|
|
elif ref_r.level > ref_r.level_compare:
|
2018-01-30 22:47:16 +01:00
|
|
|
if ref_r.level_compare == 0:
|
|
|
|
ref_r.compare = "broken"
|
|
|
|
else:
|
|
|
|
ref_r.compare = "regression"
|
2018-01-30 22:20:23 +01:00
|
|
|
elif ref_r.level < ref_r.level_compare:
|
|
|
|
ref_r.compare = "improvement"
|
|
|
|
else:
|
|
|
|
ref_r.compare = "unknown"
|
2017-12-19 17:03:51 +01:00
|
|
|
|
|
|
|
return render_template("appci_compare.html", ref=ref,
|
|
|
|
target=target,
|
|
|
|
results=ref_results)
|
|
|
|
|
2018-01-29 19:53:51 +01:00
|
|
|
@main.route('/integration/<app>')
|
|
|
|
@main.route('/integration/<app>.svg')
|
|
|
|
def badge(app):
|
|
|
|
|
|
|
|
app = App.query.filter_by(name=app).first_or_404()
|
|
|
|
branch_results = list(app.most_recent_tests_per_branch())
|
|
|
|
level = None
|
|
|
|
for r in branch_results:
|
|
|
|
if r.branch.name == "stable":
|
|
|
|
level = r.level
|
|
|
|
break
|
|
|
|
|
2018-03-16 23:34:55 +01:00
|
|
|
badge = "level%s.svg" % level if not level is None else "unknown.svg"
|
2018-01-29 19:53:51 +01:00
|
|
|
|
2018-11-07 20:12:36 +01:00
|
|
|
if not app.ci_enabled:
|
|
|
|
badge = "unknown.svg"
|
|
|
|
|
2018-01-29 19:53:51 +01:00
|
|
|
svg = open("./app/static/badges/%s" % badge).read()
|
|
|
|
response = make_response(svg)
|
|
|
|
response.content_type = 'image/svg+xml'
|
|
|
|
response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
|
|
|
|
response.headers['Pragma'] = 'no-cache'
|
|
|
|
|
|
|
|
return response
|
|
|
|
|
2018-05-30 02:31:02 +02:00
|
|
|
#
|
|
|
|
# Apps observatory
|
|
|
|
#
|
|
|
|
|
|
|
|
@main.route('/applist_history')
|
|
|
|
@main.route('/appsobservatory/history')
|
|
|
|
def appsobservatory_history():
|
|
|
|
data = json.loads(open("./app/scripts/appListsHistory/count_history.json").read())
|
|
|
|
return render_template('applist_history.html', data=data)
|
|
|
|
|
|
|
|
|
|
|
|
@main.route('/appsobservatory/rss')
|
|
|
|
def appsobservatory_rss():
|
|
|
|
file_ = open("./app/scripts/appListsHistory/atom.xml").read()
|
|
|
|
response = make_response(file_)
|
|
|
|
response.headers['Content-Type'] = 'application/rss+xml'
|
|
|
|
return response
|
|
|
|
|
2018-05-30 02:52:58 +02:00
|
|
|
@main.route('/appsobservatory/unlisted')
|
|
|
|
def appsobservatory_unlisted():
|
|
|
|
|
|
|
|
apps = sorted(UnlistedApp.query.all(), key=lambda a: a.updated_days_ago)
|
|
|
|
|
|
|
|
return render_template("unlistedapps.html", apps=apps)
|
|
|
|
|
2018-11-07 20:12:36 +01:00
|
|
|
@main.route('/app_maintainer_dash')
|
2018-12-10 23:08:17 +01:00
|
|
|
@main.route('/app_maintainer_dash/<maintainer>')
|
|
|
|
def app_maintainer_dash(maintainer=None):
|
|
|
|
|
|
|
|
if maintainer:
|
|
|
|
maintainer = maintainer.lower().replace(" ", "")
|
2018-11-07 20:12:36 +01:00
|
|
|
|
|
|
|
maintainers = set()
|
|
|
|
apps = App.query.all()
|
|
|
|
for app in apps:
|
|
|
|
for test in app.most_recent_tests_per_branch():
|
|
|
|
if test.branch.name == "stable":
|
|
|
|
app.ci_level = test.level
|
|
|
|
|
2018-11-08 14:16:07 +01:00
|
|
|
if isinstance(app.public_level, str):
|
|
|
|
app.public_level = -1
|
|
|
|
|
2020-11-12 15:35:02 +01:00
|
|
|
if app.maintained and app.state == "working":
|
2018-12-10 22:36:22 +01:00
|
|
|
maintainers.update(app.maintainers)
|
|
|
|
|
2018-11-07 20:12:36 +01:00
|
|
|
maintainers = sorted(maintainers, key=lambda m: m.lower())
|
|
|
|
apps = sorted(apps, key=lambda app: app.name.lower())
|
|
|
|
|
2018-12-10 23:08:17 +01:00
|
|
|
return render_template("maintainer.html", maintainers=maintainers, apps=apps, maintainer=maintainer)
|
2018-11-07 20:12:36 +01:00
|
|
|
|
2019-05-14 19:00:38 +02:00
|
|
|
@main.route('/testings')
|
|
|
|
def testings():
|
|
|
|
|
|
|
|
apps = App.query.filter(App.testing_pr!=None).all()
|
2020-11-05 22:23:31 +01:00
|
|
|
|
2019-05-14 19:00:38 +02:00
|
|
|
def daysAgo(date):
|
|
|
|
return (datetime.now() - date).days
|
|
|
|
|
|
|
|
for app in apps:
|
|
|
|
app.testing_pr["created_ago"] = daysAgo(app.testing_pr["created_at"])
|
|
|
|
app.testing_pr["updated_ago"] = daysAgo(app.testing_pr["updated_at"])
|
2020-11-05 22:23:31 +01:00
|
|
|
|
2019-05-14 19:00:38 +02:00
|
|
|
apps = sorted(apps, key=lambda app: (-app.testing_pr["created_ago"], -app.testing_pr["updated_ago"], app.name.lower()))
|
2020-11-05 22:23:31 +01:00
|
|
|
|
2019-05-14 19:00:38 +02:00
|
|
|
return render_template("testings.html", apps=apps)
|