+import datetime
import os
import requests
from flask import Flask, render_template, request, abort
+from flask_bootstrap import Bootstrap
from flask_caching import Cache
from flask_migrate import Migrate
+from flask_nav import Nav
+from flask_nav.elements import Navbar, Text, View
from flask_sqlalchemy import SQLAlchemy
from ui import gitlab, config, models
app = Flask(__name__)
+Bootstrap(app)
app.config.from_object(config)
cache = Cache(app)
models.db.init_app(app)
migrate = Migrate(app, models.db)
+nav = Nav(app)
+nav.register_element('top', Navbar(
+ "LineageOS Builds",
+ View('Builds', '.index'),
+ View('Runners', '.runners')
+))
headers = {'Private-Token': os.environ.get('GITLAB_TOKEN', '')}
@app.route('/')
-def main():
- return render_template('index.html', builds=models.Build.query.all())
+def index():
+ args = {}
+ if request.args:
+ if 'status' in request.args:
+ args['build_status'] = request.args.get('status')
+ if 'device' in request.args:
+ args['build_device'] = request.args.get('device')
+ if 'version' in request.args:
+ args['build_version'] = request.args.get('version')
+ if 'type' in request.args:
+ args['build_type'] = request.args.get('type')
+ if 'date' in request.args:
+ try:
+ date = datetime.datetime.strptime(request.args.get('date'), '%Y-%m-%d').date()
+ args['build_date'] = datetime.datetime.strptime(request.args.get('date'), '%Y-%m-%d').date()
+ except ValueError:
+ return "Invalid Date", 400
+ builds = models.Build.query.filter_by(**args).paginate(per_page=20)
+ return render_template('builds.html', builds=builds)
+
+@app.route('/runners/<string:runner>')
+def runner(runner):
+ runner = models.Runner.query.filter_by(runner_name=runner).first()
+ builds = models.Build.query.filter_by(build_runner=runner).paginate(per_page=20)
+ return render_template('runner.html', runner=runner, builds=builds)
+
+@app.route("/runners/")
+def runners():
+ runners = models.Runner.query.all()
+ return render_template('runners.html', runners=runners)
@app.route("/webhook", methods=('POST',))
def process_webhook():
--- /dev/null
+"""Add sponsor
+
+Revision ID: 37e70676c947
+Revises: 448614888e24
+Create Date: 2018-10-29 23:10:07.331088
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+
+# revision identifiers, used by Alembic.
+revision = '37e70676c947'
+down_revision = '448614888e24'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+ # ### commands auto generated by Alembic - please adjust! ###
+ op.add_column('runner', sa.Column('runner_sponsor', sa.String(), nullable=True))
+ op.add_column('runner', sa.Column('runner_sponsor_url', sa.String(), nullable=True))
+ # ### end Alembic commands ###
+
+
+def downgrade():
+ # ### commands auto generated by Alembic - please adjust! ###
+ with op.batch_alter_table('runner') as batch_op:
+ batch_op.drop_column('runner_sponsor')
+ batch_op.drop_column('runner', 'runner_sponsor_url')
+ # ### end Alembic commands ###
runner_id = db.Column(db.String, primary_key=True, autoincrement=False)
runner_name = db.Column(db.String)
+ runner_sponsor = db.Column(db.String)
+ runner_sponsor_url = db.Column(db.String)
+
@classmethod
def get_or_create_by_id(cls, runner_id):
runner = cls.query.filter_by(runner_id=runner_id).first()
--- /dev/null
+.navbar-default {
+ background-color: #167c80;
+}
+
+.navbar-default .navbar-brand {
+ color: white;
+}
+
+.navbar-default .navbar-nav li a {
+ color: white;
+ font-weight: 400;
+}
+
+a {
+ color: #167c80;
+}
+
+a:focus, a:hover {
+ color: #167c80;
+ text-decoration: underline;
+}
+
+.pagination .active a {
+ background-color: #167c80;
+}
+
+.pagination li a, .pagination li a:focus, .pagination li a:hover {
+ color: #167c80;
+}
--- /dev/null
+{%- extends "bootstrap/base.html" %}
+
+{% block title %}LineageOS Builds{% endblock %}
+
+{% import "bootstrap/fixes.html" as fixes %}
+{% block head %}
+{{super()}}
+{{fixes.ie8()}}
+{%- endblock %}
+
+{% block styles -%}
+ {{super()}}
+ <link rel="stylesheet" href="{{url_for('.static', filename='custom.css')}}">
+{% endblock %}
+
+{% block navbar %}
+{{nav.top.render()}}
+{% endblock %}
+
--- /dev/null
+{%- extends "base.html" %}
+
+
+{% import "bootstrap/utils.html" as utils %}
+{% from "bootstrap/pagination.html" import render_pagination %}
+{% block content %}
+ <div class="container">
+ <table class="table table-striped">
+ <tr>
+ <th scope="col">ID</th>
+ <th scope="col">Status</th>
+ <th scope="col">Device</th>
+ <th scope="col">Version</th>
+ <th scope="col">Type</th>
+ <th scope="col">Date</th>
+ <th scope="col">Runner</th>
+ </tr>
+ {% for build in builds.items %}
+ <tr>
+ <th scope="row"><a href="https://gitlab.com/LineageOS/builder/android/pipelines/{{build.build_id}}">{{build.build_id}}</a></td>
+ <td>{{build.build_status}}</td>
+ <td>{{build.build_device}}</td>
+ <td>{{build.build_version}}</td>
+ <td>{{build.build_type}}</td>
+ <td>{{build.build_date}}</td>
+ <td><a href="/runners/{{build.build_runner.runner_name}}">{{build.build_runner.runner_name}}</a></td>
+ </tr>
+ {% endfor %}
+ </table>
+ {{render_pagination(builds)}}
+ </div>
+{% endblock %}
+++ /dev/null
- <!DOCTYPE html>
-<html>
- <head>
- <meta charset="UTF-8">
- <title>LineageOS Builds</title>
- <style>
- table {
- border: solid 1px #167c80;
- border-collapse: collapse;
- border-spacing: 0;
- }
- table th {
- background-color: #167c80;
- color: white;
- padding: 10px;
- text-align: left;
- }
- table td {
- padding: 10px;
- }
- </style>
- </head>
- <body>
- <table>
- <tr>
- <th>ID</th>
- <th>Status</th>
- <th>Device</th>
- <th>Version</th>
- <th>Type</th>
- <th>Date</th>
- <th>Runner</th>
- </tr>
- {% for build in builds %}
- <tr>
- <td><a href="https://gitlab.com/LineageOS/builder/android/pipelines/{{build.build_id}}">{{build.build_id}}</a></td>
- <td>{{build.build_status}}</td>
- <td>{{build.build_device}}</td>
- <td>{{build.build_version}}</td>
- <td>{{build.build_type}}</td>
- <td>{{build.build_date}}</td>
- <td><a href="/runners/{{build.build_runner.runner_name}}">{{build.build_runner.runner_name}}</a></td>
- </tr>
- {% endfor %}
- </table>
- </body>
-</html>
-
--- /dev/null
+{%- extends "base.html" %}
+
+
+{% import "bootstrap/utils.html" as utils %}
+{% from "bootstrap/pagination.html" import render_pagination %}
+{% block content %}
+ <div class="container">
+ Builds on {{runner.runner_name}}
+ {%- if runner.runner_sponsor and runner.runner_sponsor_url %}
+ (provided by <a href="{{runner.sponsor_url}}">{{runner.runner_sponsor}}</a>)
+ {%- elif runner.runner_sponsor %}
+ (provided by {{runner.runner_sponsor}})
+ {% endif %}
+ <table class="table table-striped">
+ <tr>
+ <th scope="col">ID</th>
+ <th scope="col">Status</th>
+ <th scope="col">Device</th>
+ <th scope="col">Version</th>
+ <th scope="col">Type</th>
+ <th scope="col">Date</th>
+ </tr>
+ {% for build in builds.items %}
+ <tr>
+ <th scope="row"><a href="https://gitlab.com/LineageOS/builder/android/pipelines/{{build.build_id}}">{{build.build_id}}</a></td>
+ <td>{{build.build_status}}</td>
+ <td>{{build.build_device}}</td>
+ <td>{{build.build_version}}</td>
+ <td>{{build.build_type}}</td>
+ <td>{{build.build_date}}</td>
+ </tr>
+ {% endfor %}
+ </table>
+ {{render_pagination(builds)}}
+ </div>
+{% endblock %}
--- /dev/null
+{%- extends "base.html" %}
+
+
+{% import "bootstrap/utils.html" as utils %}
+{% block content %}
+ <div class="container">
+ <table class="table table-striped">
+ <tr>
+ <th scope="col">Name</th>
+ <th scope="col">Sponsor</th>
+ </tr>
+ {% for runner in runners %}
+ <tr>
+ <td><a href="/runners/{{runner.runner_name}}">{{runner.runner_name}}</a></td>
+ <td>{% if runner.runner_sponsor_url %}<a href="{{runner.runner_sponsor_url}}">{% endif %}{{runner.runner_sponsor}}{% if runner.runner_sponsor_url %}</a>{% endif %}</td>
+ </tr>
+ {% endfor %}
+ </table>
+ </div>
+{% endblock %}