[Pkg-debile-commits] [debile-web] 01/01: WIP: Update debile-web to current db schema and terminology.
Jon Severinsson
jonno-guest at moszumanska.debian.org
Thu Mar 13 17:55:58 UTC 2014
This is an automated email from the git hooks/post-receive script.
jonno-guest pushed a commit to branch master
in repository debile-web.
commit c7c3ee6347b9626f3a7bf17aca8d02e86b804330
Author: Jon Severinsson <jon at severinsson.net>
Date: Tue Mar 11 20:52:04 2014 +0100
WIP: Update debile-web to current db schema and terminology.
---
debileweb/blueprints/consts.py | 2 +
debileweb/blueprints/forms.py | 2 +-
debileweb/blueprints/frontend.py | 843 +++++++++++---------
static/css/jquery-ui.css | 1175 ----------------------------
templates/builder.html | 36 +
templates/builder_list_fragment.html | 37 +
templates/group.html | 57 +-
templates/group_list_fragment.html | 28 +
templates/index.html | 38 +-
templates/job.html | 103 +++
templates/job_list_fragment.html | 60 +-
templates/jobs.html | 14 +
templates/machine.html | 11 -
templates/machine_list_fragment.html | 21 -
templates/macros.inc.html | 10 -
templates/prefix.html | 8 -
templates/prefix_list.html | 37 -
templates/report.html | 35 -
templates/report_desc_binary.html | 44 --
templates/report_desc_source.html | 36 -
templates/report_list_binary_fragment.html | 37 -
templates/report_list_fragment.html | 52 --
templates/repository.html | 21 -
templates/search.html | 14 +-
templates/source-not-found.html | 6 +-
templates/source.html | 78 +-
templates/source_list.html | 8 -
templates/source_list_fragment.html | 50 +-
templates/sources.html | 14 +
templates/user.html | 42 +
templates/worker.html | 19 -
31 files changed, 927 insertions(+), 2011 deletions(-)
diff --git a/debileweb/blueprints/consts.py b/debileweb/blueprints/consts.py
index cdd3164..c6e436b 100644
--- a/debileweb/blueprints/consts.py
+++ b/debileweb/blueprints/consts.py
@@ -28,3 +28,5 @@ PREFIXES = [
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
]
+ENTRIES_PER_PAGE = 20
+ENTRIES_PER_LIST_PAGE = 100
diff --git a/debileweb/blueprints/forms.py b/debileweb/blueprints/forms.py
index 68cbf8c..6bc1c89 100644
--- a/debileweb/blueprints/forms.py
+++ b/debileweb/blueprints/forms.py
@@ -23,5 +23,5 @@ from wtforms.validators import Required
class SearchPackageForm(Form):
- package = TextField('package', validators=[Required()])
+ source = TextField('source', validators=[Required()])
maintainer = TextField('maintainer', validators=[Required()])
diff --git a/debileweb/blueprints/frontend.py b/debileweb/blueprints/frontend.py
index 48e7153..9caac9d 100644
--- a/debileweb/blueprints/frontend.py
+++ b/debileweb/blueprints/frontend.py
@@ -1,6 +1,7 @@
# Copyright (c) 2012 Paul Tagliamonte <paultag at debian.org>
# Copyright (c) 2013 Leo Cavaille <leo at cavaille.net>
# Copyright (c) 2013 Sylvestre Ledru <sylvestre at debian.org>
+# Copyright (c) 2014 Jon Severinsson <jon at severinsson.net>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
@@ -20,28 +21,21 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
-from flask import Blueprint, render_template, send_file, request, redirect
+from flask import Blueprint, render_template, request, redirect
from flask.ext.jsonpify import jsonify
-
-from sqlalchemy import func
from sqlalchemy.orm import joinedload
-from sqlalchemy.sql.expression import bindparam
+from debile.master.utils import make_session
+from debile.master.orm import (Person, Builder, Suite, Component, Arch, Check,
+ Group, GroupSuite, Source, Maintainer, Binary,
+ Job, JobDependencies, Result)
-from debilemaster.orm import Source, Binary, Machine, User, Job, Group
-from debilemaster.config import Config
-from debilemaster.server import Session
-from debilemaster.archive import UserRepository
+from debileweb.blueprints.forms import SearchPackageForm
+from debileweb.blueprints.consts import PREFIXES, ENTRIES_PER_PAGE, ENTRIES_PER_LIST_PAGE
+from datetime import datetime
from humanize import naturaltime
-from humanize.time import naturaldelta
-
-from datetime import timedelta
-import datetime as dt
-import os.path
-import re
-from forms import SearchPackageForm
-from consts import PREFIXES_DEFAULT
+import os
frontend = Blueprint('frontend', __name__, template_folder='templates')
@@ -50,442 +44,549 @@ frontend = Blueprint('frontend', __name__, template_folder='templates')
def ago_display(when):
if when is None:
return "never"
- td = dt.datetime.utcnow() - when
+ td = datetime.utcnow() - when
return naturaltime(td)
-def get_packages_prefixes():
- """
- returns the packages prefixes (a, b, ..., liba, libb, ..., y, z)
- Note that this could be computed from the database ... but since we
- are rebuilding Debian, we will have all letters + lib*
- """
- return PREFIXES_DEFAULT
-
-def get_package_link(p):
- if p.type == "source":
- return "/source/%s/%s/%s/%s" % (p.user.login, p.name, p.version, p.run)
- else:
- return "/notimplementedyet"
-
-
-def get_machine_link(m):
- return "/machine/%s" % m.name
-
-
@frontend.route("/")
def index():
- session = Session()
- active_jobs = session.query(Job)\
- .options(joinedload('machine'))\
- .filter(Job.machine != None)\
- .filter(Job.finished_at == None)\
+ session = make_session()
+
+ groups = session.query(Group)\
+ .order_by(Group.name.asc())\
.all()
- machines = session.query(Machine).options(joinedload('jobs')).all()
- active_jobs_info = []
- for j in active_jobs:
+ builders = session.query(Builder)\
+ .order_by(Builder.name.asc())\
+ .all()
+
+ groups_info = []
+ for group in groups:
info = {}
- info['job'] = j
- info['package_link'] = get_package_link(j.package)
- if j.machine:
- info['machine_link'] = get_machine_link(j.machine)
- active_jobs_info.append(info)
+ info['group'] = group
+ info['group_link'] = "/group/%s" % group.name
+ info['maintainer_link'] = "/user/%s" % group.maintainer.email
+ groups_info.append(info)
+
+ builders_info = []
+ for builder in builders:
+ info = {}
+ info['builder'] = builder
+ info['builder_link'] = "/builder/%s" % builder.name
+ info['maintainer_link'] = "/user/%s" % group.maintainer.email
+ jobs = session.query(Job).join(Source)\
+ .filter(Job.assigned_at != None)\
+ .filter(Job.finished_at == None)\
+ .filter(Job.builder == builder)\
+ .order_by(Job.id.desc())\
+ .all()
+ jobs_info = []
+ for job in jobs:
+ jobinfo = {}
+ jobinfo['job'] = job
+ jobinfo['job_link'] = "/job/%s/%s/%s/%s" % \
+ (job.group.name, job.source.name, job.source.version, job.id)
+ jobinfo['source_link'] = "/source/%s/%s/%s" % \
+ (job.group.name, job.source.name, job.source.version)
+ jobs_info.append(jobinfo)
+ info['jobs_info'] = jobs_info
+ builders_info.append(info)
pending_jobs = session.query(Job)\
.filter(Job.assigned_at == None)\
.count()
-
form = SearchPackageForm()
- packages_prefixes = get_packages_prefixes()
return render_template('index.html', **{
- "active_jobs_info": active_jobs_info,
+ "groups_info": groups_info,
+ "builders_info": builders_info,
"pending_jobs": pending_jobs,
- "packages_prefixes": packages_prefixes,
+ "prefixes": PREFIXES,
"form": form
})
+
+ at frontend.route("/maintainer/<search>/", methods=['POST', 'GET'])
+ at frontend.route("/maintainer/<search>/<page>")
+ at frontend.route("/source/<search>/", methods=['POST', 'GET'])
+ at frontend.route("/source/<search>/<page>")
@frontend.route("/sources/")
-def source_list():
- session = Session()
- count = 100
- sources = session.query(Source)\
- .options(joinedload(Source.user))\
- .options(joinedload(Source.group))\
- .order_by(Source.created_at.desc())\
- .limit(count)
+ at frontend.route("/sources/<prefix>/")
+ at frontend.route("/sources/<prefix>/<page>/")
+def sources(search="", prefix="recent", page=0):
+ page = int(page)
+ session = make_session()
+
+ if request.path == "/maintainer/search/":
+ return redirect('/maintainer/' + request.form['maintainer'] + '/')
+ if request.path == "/source/search/":
+ return redirect('/source/' + request.form['source'] + '/')
+
+ if request.path.startswith("/maintainer/"):
+ source_count = session.query(Source)\
+ .count()
+ desc = "Search results for maintainer '%s'" % search
+ source_count = session.query(Source)\
+ .filter(Source.maintainers.any(Maintainer.name.contains(search) |
+ Maintainer.email.contains(search)))\
+ .count()
+ sources = session.query(Source)\
+ .filter(Source.maintainers.any(Maintainer.name.contains(search) |
+ Maintainer.email.contains(search)))\
+ .order_by(Source.name.asc(), Source.id.desc())\
+ .offset(page * ENTRIES_PER_LIST_PAGE)\
+ .limit(ENTRIES_PER_LIST_PAGE)\
+ .all()
+ elif request.path.startswith("/source/"):
+ desc = "Search results for source '%s'" % search
+ source_count = session.query(Source)\
+ .filter(Source.name.contains(search))\
+ .count()
+ sources = session.query(Source)\
+ .filter(Source.name.contains(search))\
+ .order_by(Source.name.asc(), Source.id.desc())\
+ .offset(page * ENTRIES_PER_LIST_PAGE)\
+ .limit(ENTRIES_PER_LIST_PAGE)\
+ .all()
+ elif prefix == "recent":
+ desc = "All recent sources."
+ source_count = session.query(Source).count()
+ sources = session.query(Source)\
+ .order_by(Source.id.desc())\
+ .offset(page * ENTRIES_PER_LIST_PAGE)\
+ .limit(ENTRIES_PER_LIST_PAGE)\
+ .all()
+ elif prefix == "incomplete":
+ desc = "All incomplete sources."
+ source_count = session.query(Source)\
+ .filter(Source.jobs.any(Job.finished_at == None))\
+ .count()
+ sources = session.query(Source)\
+ .filter(Source.jobs.any(Job.finished_at == None))\
+ .order_by(Source.name.asc(), Source.id.desc())\
+ .offset(page * ENTRIES_PER_LIST_PAGE)\
+ .limit(ENTRIES_PER_LIST_PAGE)\
+ .all()
+ elif prefix == "l":
+ desc = "All sources for packages beginning with 'l'"
+ source_count = session.query(Source)\
+ .filter(Source.name.startswith("l"))\
+ .filter(~Source.name.startswith("lib"))\
+ .count()
+ sources = session.query(Source)\
+ .filter(Source.name.startswith("l"))\
+ .filter(~Source.name.startswith("lib"))\
+ .order_by(Source.name.asc(), Source.id.desc())\
+ .offset(page * ENTRIES_PER_LIST_PAGE)\
+ .limit(ENTRIES_PER_LIST_PAGE)\
+ .all()
+ else:
+ desc = "All sources for packages beginning with '%s'" % prefix
+ source_count = session.query(Source)\
+ .filter(Source.name.startswith(prefix))\
+ .count()
+ sources = session.query(Source)\
+ .filter(Source.name.startswith(prefix))\
+ .order_by(Source.name.asc(), Source.id.desc())\
+ .offset(page * ENTRIES_PER_LIST_PAGE)\
+ .limit(ENTRIES_PER_LIST_PAGE)\
+ .all()
+
sources_info = []
- for s in sources:
+ for source in sources:
info = {}
- info['source'] = s
- info['source_link'] = "/source/%s/%s/%s/%s" % (s.user.login, s.name, s.version, s.run)
- info['group_link'] = "/group/%s" % s.group.name
- info['user_link'] = "/worker/%s" % s.user.login
- info['user_repository_link'] = "/repository/%s" % s.user.login
+ info['source'] = source
+ info['source_link'] = "/source/%s/%s/%s" % \
+ (source.group.name, source.name, source.version)
+ info['group_link'] = "/group/%s" % source.group.name
+ info['uploader_link'] = "/user/%s" % source.uploader.email
sources_info.append(info)
- return render_template('source_list.html', **{
+ info = {}
+ info['desc'] = desc
+ info['prev_link'] = "/sources/%s/%d" % (prefix, page-1) \
+ if page > 0 else None
+ info['next_link'] = "/sources/%s/%d" % (prefix, page+1) \
+ if source_count > (page+1) * ENTRIES_PER_LIST_PAGE else None
+
+ return render_template('sources.html', **{
+ "info": info,
"sources_info": sources_info,
- "count": count,
})
+ at frontend.route("/jobs/")
+ at frontend.route("/jobs/<prefix>/")
+ at frontend.route("/jobs/<prefix>/<page>/")
+def jobs(prefix="recent", page=0):
+ page = int(page)
+ session = make_session()
+
+ if prefix == "recent":
+ desc = "All recent jobs."
+ job_count = session.query(Job).count()
+ jobs = session.query(Job).join(Source).join(Check)\
+ .order_by(Source.id.desc())\
+ .offset(page * ENTRIES_PER_LIST_PAGE)\
+ .limit(ENTRIES_PER_LIST_PAGE)\
+ .all()
+ elif prefix == "incomplete":
+ desc = "All incomplete jobs."
+ job_count = session.query(Job)\
+ .filter(Job.finished_at == None)\
+ .count()
+ jobs = session.query(Job).join(Source).join(Check)\
+ .filter(Job.finished_at == None)\
+ .order_by(Source.name.asc(), Source.id.desc(),
+ Check.build.desc(), Check.id.asc(),
+ Job.id.asc())\
+ .offset(page * ENTRIES_PER_LIST_PAGE)\
+ .limit(ENTRIES_PER_LIST_PAGE)\
+ .all()
+ elif prefix == "l":
+ desc = "All jobs for packages beginning with 'l'"
+ job_count = session.query(Job).join(Source)\
+ .filter(Source.name.startswith("l"))\
+ .filter(~Source.name.startswith("lib"))\
+ .count()
+ jobs = session.query(Job).join(Source).join(Check)\
+ .filter(Source.name.startswith("l"))\
+ .filter(~Source.name.startswith("lib"))\
+ .order_by(Source.name.asc(), Source.id.desc(),
+ Check.build.desc(), Check.id.asc(),
+ Job.id.asc())\
+ .offset(page * ENTRIES_PER_LIST_PAGE)\
+ .limit(ENTRIES_PER_LIST_PAGE)\
+ .all()
+ else:
+ desc = "All jobs for packages beginning with '%s'" % prefix
+ job_count = session.query(Job).join(Source)\
+ .filter(Source.name.startswith(prefix))\
+ .count()
+ jobs = session.query(Job).join(Source).join(Check)\
+ .filter(Source.name.startswith(prefix))\
+ .order_by(Source.name.asc(), Source.id.desc(),
+ Check.build.desc(), Check.id.asc(),
+ Job.id.asc())\
+ .offset(page * ENTRIES_PER_LIST_PAGE)\
+ .limit(ENTRIES_PER_LIST_PAGE)\
+ .all()
+
+ jobs_info = []
+ for job in jobs:
+ info = {}
+ info['job'] = job
+ info['job_link'] = "/job/%s/%s/%s/%s" % \
+ (job.group.name, job.source.name, job.source.version, job.id)
+ info['source_link'] = "/source/%s/%s/%s" % \
+ (job.group.name, job.source.name, job.source.version)
+ info['group_link'] = "/group/%s" % job.group.name
+ info['builder_link'] = "/builder/%s" % job.builder.name \
+ if job.builder else None
+ jobs_info.append(info)
+
+ info = {}
+ info['desc'] = desc
+ info['prev_link'] = "/jobs/%s/%d" % (prefix, page-1) \
+ if page > 0 else None
+ info['next_link'] = "/jobs/%s/%d" % (prefix, page+1) \
+ if job_count > (page+1) * ENTRIES_PER_LIST_PAGE else None
+
+ return render_template('jobs.html', **{
+ "info": info,
+ "jobs_info": jobs_info,
+ })
- at frontend.route("/maintainer/<nameItem>/", methods=['POST','GET'])
- at frontend.route("/prefix/<nameItem>/")
-def list_packages(nameItem=0):
- if request.method == 'POST':
- # Switch a better url
- return redirect('/maintainer/' + re.search(r".*<(.*)>",request.form['maintainer']).group(1) + '/')
- session = Session()
- if request.path.startswith("/maintainer/"):
- # Maintainer
- sources = session.query(Source)\
- .filter(Source.maintainer.contains(nameItem))\
- .distinct(Source.name)\
- .order_by(Source.name.desc(), Source.version.desc())
- else:
- sources = session.query(Source)\
- .filter(Source.name.startswith(nameItem))\
- .distinct(Source.name)\
- .order_by(Source.name.desc(), Source.version.desc())
+ at frontend.route("/group/<name>/")
+ at frontend.route("/group/<name>/<page>/")
+def group(name, page=0):
+ page = int(page)
+ session = make_session()
+
+ group = session.query(Group)\
+ .filter(Group.name == name)\
+ .one()
+
+ source_count = session.query(Source)\
+ .filter(Source.group == group)\
+ .count()
+ sources = session.query(Source)\
+ .filter(Source.group == group)\
+ .order_by(Source.id.desc())\
+ .offset(page * ENTRIES_PER_PAGE)\
+ .limit(ENTRIES_PER_PAGE)\
+ .all()
sources_info = []
- for s in sources:
+ for source in sources:
info = {}
- info['source'] = s
- info['source_link'] = "/source/%s/%s/%s/%s" % (s.user.login, s.name, "latest", s.run)
+ info['source'] = source
+ info['source_link'] = "/source/%s/%s/%s" % \
+ (source.group.name, source.name, source.version)
+ info['uploader_link'] = "/user/%s" % source.uploader.email
sources_info.append(info)
- return render_template('prefix.html', **{
- "sources": sources_info,
- "prefix": nameItem,
+ info = {}
+ info['maintainer_link'] = "/user/%s" % group.maintainer.email
+ info['prev_link'] = "/group/%s/%d" % (group.name, page-1) \
+ if page > 0 else None
+ info['next_link'] = "/group/%s/%d" % (group.name, page+1) \
+ if source_count > (page+1) * ENTRIES_PER_PAGE else None
+
+ return render_template('group.html', **{
+ "group": group,
+ "info": info,
+ "sources_info": sources_info,
})
- at frontend.route("/group/<group_id>/")
- at frontend.route("/group/<group_id>/<page>/")
-def group_list(group_id, page=0):
+
+ at frontend.route("/builder/<name>")
+ at frontend.route("/builder/<name>/<page>")
+def builder(name, page=0):
page = int(page)
- # FIXME : unsafe code, catch exceptions
- session = Session()
- g = session.query(Group).filter(Group.name == group_id).one()
- sources = session.query(Source).filter(Source.group == g).order_by(Source.created_at.asc()).paginate(page, per_page=15)
+ session = make_session()
+
+ builder = session.query(Builder)\
+ .filter(Builder.name == name)\
+ .one()
+
+ job_count = session.query(Job).filter(Job.builder == builder).count()
+ jobs = session.query(Job).join(Source)\
+ .filter(Job.builder == builder)\
+ .order_by(Job.id.desc())\
+ .offset(page * ENTRIES_PER_PAGE)\
+ .limit(ENTRIES_PER_PAGE)\
+ .all()
- return render_template('group.html', **{
- "sources": sources,
- "group_id": group_id,
- "page": page,
+ jobs_info = []
+ for job in jobs:
+ info = {}
+ info['job'] = job
+ info['job_link'] = "/job/%s/%s/%s/%s" % \
+ (job.group.name, job.source.name, job.source.version, job.id)
+ info['source_link'] = "/source/%s/%s/%s" % \
+ (job.group.name, job.source.name, job.source.version)
+ info['group_link'] = "/group/%s" % job.group.name
+ jobs_info.append(info)
+
+ info = {}
+ info['maintainer_link'] = "/user/%s" % builder.maintainer.email
+ info['prev_link'] = "/builder/%s/%d" % (builder.name, page-1) \
+ if page > 0 else None
+ info['next_link'] = "/builder/%s/%d" % (builder.name, page+1) \
+ if job_count > (page+1) * ENTRIES_PER_PAGE else None
+
+ return render_template('machine.html', **{
+ "builder": builder,
+ "jobs_info": jobs_info,
+ "info": info,
})
- at frontend.route("/source/search/", methods=['POST'])
- at frontend.route("/source/<owner_name>/<package_name>/<package_version>/<int:run_number>")
-def source(package_name="", owner_name="fred", package_version="latest", run_number=1):
- if request.method == 'POST':
- # Switch a better url
- return redirect('/source/' + owner_name + '/' + request.form['package'] + '/' + package_version + '/' + str(run_number))
+ at frontend.route("/user/<email>/")
+ at frontend.route("/user/<email>/<page>/")
+def user(email, page=0):
+ page = int(page)
+ session = make_session()
- session = Session()
+ user = session.query(Person)\
+ .filter(Person.email == email)\
+ .one()
- # Let's compute all the versions that exists for this package
- versions_query = session.query(Source.version)\
- .join(Source.user)\
- .filter(Source.name == package_name)\
- .filter(User.login == owner_name)
- versions = sorted(set([e[0] for e in versions_query.all()]))
+ groups = session.query(Group)\
+ .filter(Group.maintainer == user)\
+ .order_by(Group.name.asc())\
+ .all()
- if len(versions) == 0:
- return render_template('source-not-found.html', **{
- "package_name": package_name
- })
+ builders = session.query(Builder)\
+ .filter(Builder.maintainer == user)\
+ .order_by(Builder.name.asc())\
+ .all()
- latest_version = versions[-1]
- if package_version == 'latest':
- this_version = latest_version
- else:
- this_version = package_version
+ source_count = session.query(Source)\
+ .filter(Source.uploader == user)\
+ .count()
+ sources = session.query(Source)\
+ .filter(Source.uploader == user)\
+ .order_by(Source.id.desc())\
+ .offset(page * ENTRIES_PER_PAGE)\
+ .limit(ENTRIES_PER_PAGE)\
+ .all()
+
+ groups_info = []
+ for group in groups:
+ info = {}
+ info['group'] = group
+ info['group_link'] = "/group/%s" % group.name
+ groups_info.append(info)
+
+ builders_info = []
+ for builder in builders:
+ info = {}
+ info['builder'] = builders
+ info['builder_link'] = "/builder/%s" % builder.name
+ jobs = session.query(Job).join(Source)\
+ .filter(Job.assigned_at != None)\
+ .filter(Job.finished_at == None)\
+ .filter(Job.builder == builder)\
+ .order_by(Job.id.desc())\
+ .all()
+ jobs_info = []
+ for job in jobs:
+ jobinfo = {}
+ jobinfo['job'] = job
+ jobinfo['job_link'] = "/job/%s/%s/%s/%s" % \
+ (job.group.name, job.source.name, job.source.version, job.id)
+ jobinfo['source_link'] = "/source/%s/%s/%s" % \
+ (job.group.name, job.source.name, job.source.version)
+ jobs_info.append(jobinfo)
+ info['jobs_info'] = jobs_info
+ builders_info.append(info)
+
+ sources_info = []
+ for source in sources:
+ info = {}
+ info['source'] = source
+ info['source_link'] = "/source/%s/%s/%s" % \
+ (source.group.name, source.name, source.version)
+ info['group_link'] = "/group/%s" % source.group.name
+ sources_info.append(info)
- # All runs that exist for this version
- runs_query = session.query(Source.run)\
- .join(Source.user)\
+ info = {}
+ info['prev_link'] = "/user/%s/%d" % (user.email, page-1) \
+ if page > 0 else None
+ info['next_link'] = "/user/%s/%d" % (user.email, page+1) \
+ if source_count > (page+1) * ENTRIES_PER_PAGE else None
+
+ return render_template('user.html', **{
+ "user": user,
+ "info": info,
+ "groups_info": groups,
+ "builders_info": builders,
+ "sources_info": sources,
+ })
+
+
+ at frontend.route("/source/<group_name>/<package_name>/<suite_or_version>/")
+def source(group_name, package_name, suite_or_version):
+ session = make_session()
+
+ source = session.query(Source.version)\
+ .filter(Group.name == group_name)\
.filter(Source.name == package_name)\
- .filter(User.login == owner_name)\
- .filter(Source.version == this_version)\
- .order_by(Source.run.asc())
- runs = [e[0] for e in runs_query.all()]
+ .filter(Source.version == suite_or_version |
+ Suite.name == suite_or_version)\
+ .order_by(Source.id.desc()).first()
- if len(runs) == 0:
+ if not source:
return render_template('source-not-found.html', **{
- "package_name": package_name,
- "version": this_version
- })
-
-
- latest_run = runs[-1]
- if run_number == '0':
- this_run = latest_run
- else:
- this_run = run_number
-
- # Join load the user to show details about the source owner
- package_query = session.query(Source)\
- .options(joinedload('user'))\
- .options(joinedload('jobs'))\
- .options(joinedload('binaries'))\
+ "group_name": group_name,
+ "package_name": package_name,
+ "suite_or_version": suite_or_version,
+ })
+
+ # Find all versions of this package
+ versions = session.query(Source.version)\
+ .filter(Group.name == group_name)\
.filter(Source.name == package_name)\
- .filter(User.login == owner_name)\
- .filter(Source.version == this_version)\
- .filter(Source.run == this_run)
-
- try:
- package = package_query.one()
- except:
- raise Exception("This resource does not exist")
-
- # Compute description section
- desc = {}
- desc['user_link'] = "/worker/%s" % package.user.login
- desc['user_repository_link'] = "/repository/%s" % package.user.login
-
- desc['run'] = run_number
- # desc['pool_link'] =
-
- # Fill in the run sections if need be
- # Remember that multiple runs cannot exist with fred auto-build
- if len(runs) > 1:
- multiple_runs = True
- else:
- multiple_runs = False
- runs_info = []
- if multiple_runs:
- for r in runs:
- href = "/source/%s/%s/%s/%s" % (owner_name,
- package_name,
- package_version,
- r
- )
- runs_info.append((r, href))
-
- # Fill in the version sections
- if len(versions) > 1:
- multiple_versions = True
- else:
- multiple_versions = False
+ .order_by(Source.id.desc()).all()
+
versions_info = []
- if multiple_versions:
- for v in versions:
- href = "/source/%s/%s/%s/%s" % (owner_name, package_name, v, 1)
- versions_info.append((v, href))
-
- # Compute infos to display the job parts
- # Iterate through all jobs
- # Job total counters + compute some links
- source_jobs = session.query(Job)\
- .options(joinedload('machine'))\
- .filter(Job.package == package)\
- .order_by(Job.type, Job.subtype)\
+ if len(versions) > 1:
+ for version in versions:
+ href = "/source/%s/%s/%s" % \
+ (group_name, package_name, version)
+ versions_info.append((version, href))
+
+ jobs = session.query(Job).join(Check)\
+ .filter(Job.source == source)\
+ .order_by(Check.build.desc(), Check.id.asc(), Job.id.asc())\
.all()
- total = len(source_jobs)
+ total = len(jobs)
unfinished = 0
- source_jobs_info = []
- for j in source_jobs:
+ jobs_info = []
+ for job in jobs:
info = {}
- info['job'] = j
- info['job_link'] = '/report/%s/%s/%s/%s#full_log' % (package_name, this_version, j.type, j.id)
- if j.type == "clanganalyzer":
- # Special case (I know) for clang to point directly to the HTML report
- # TODO: update the path to a nicer one (like job_link)
- info['job_report_link'] = '/static-job-reports/%s/scan-build/' % j.id
- else:
- info['job_report_link'] = info['job_link']
- if j.machine:
- info['job_machine_link'] = '/machine/%s' % j.machine.name
- if not j.is_finished():
+ info['job'] = job
+ info['job_link'] = '/job/%s/%s/%s/%d' % \
+ (group_name, package_name, source.version, job.id)
+ info['builder_link'] = '/builder/%s' % job.builder.name \
+ if job.builder else None
+ if job.finished_at is None:
unfinished += 1
- if j.machine is None:
- info['status'] = 'pending'
- else:
- info['status'] = 'running'
+ info['status'] = 'running' if job.assigned_at else 'pending'
else:
info['status'] = 'finished'
- source_jobs_info.append(info)
-
- binaries_jobs = session.query(Job)\
- .options(joinedload('machine'))\
- .join(Binary, Job.package_id == Binary.package_id)\
- .filter(Binary.source_id == package.source_id)\
- .order_by(Job.type, Job.subtype, Binary.name)\
- .all()
+ jobs_info.append(info)
- binaries_jobs_info = []
- for j in binaries_jobs:
- info = {}
- info['job'] = j
- info['job_link'] = '/report/%s/%s/%s/%s#full_log' % (package_name, this_version, j.type, j.id)
- if j.machine:
- info['job_machine_link'] = '/machine/%s' % j.machine.name
- if not j.is_finished():
- unfinished += 1
- if j.machine:
- info['status'] = 'running'
- else:
- info['status'] = 'pending'
- else:
- info['status'] = 'finished'
- binaries_jobs_info.append(info)
+ info = {}
+ info["job_status"] = (total, unfinished),
+ info['group_link'] = "/group/%s" % source.group.name
+ info['uploader_link'] = "/user/%s" % source.uploader.name
return render_template('source.html', **{
- "desc": desc,
- "multiple_runs": multiple_runs,
- "runs_info": runs_info,
- "latest_run": latest_run,
- "multiple_versions": multiple_versions,
- "latest_version": latest_version,
+ "job": job,
+ "info": info,
"versions_info": versions_info,
- "package": package,
- "package_job_status": (total, unfinished),
- "source_jobs_info": source_jobs_info,
- "binaries_jobs_info": binaries_jobs_info
- })
-
-
- at frontend.route("/machine/<machine_name>")
-def machine(machine_name):
- session = Session()
- # FIXME : unsafe code, catch exceptions
- machine = session.query(Machine).filter(Machine.name == machine_name).one()
- return render_template('machine.html', **{
- "machine": machine
+ "jobs_info": jobs_info,
})
- at frontend.route("/worker/<worker_login>")
-def worker(worker_login):
- session = Session()
- # FIXME : unsafe code, catch exceptions
- user = session.query(User).filter(User.login == worker_login).one()
+ at frontend.route("/job/<job_id>/")
+ at frontend.route("/job/<group_name>/<package_name>/<package_version>/<job_id>/")
+def job(job_id, group_name="", package_name="", version=""):
+ job_id = int(job_id)
+ session = make_session()
- ur = UserRepository(user)
- dput_upload_profile = ur.generate_dputprofile()
-
- return render_template('worker.html', **{
- "worker": user,
- "dput_upload_profile": dput_upload_profile
- })
+ job = session.query(Job).get(job_id)
- at frontend.route("/repository/<worker_login>")
-def repository(worker_login):
- session = Session()
- # FIXME : unsafe code, catch exceptions
- user = session.query(User).filter(User.login == worker_login).one()
-
- ur = UserRepository(user)
- apt_binary_list = ur.generate_aptbinarylist()
- apt_source_list = ur.generate_aptsourcelist()
-
- return render_template('repository.html', **{
- "worker": user,
- "apt_binary_list": apt_binary_list,
- "apt_source_list": apt_source_list
- })
-
-
- at frontend.route("/report/<job_id>/")
- at frontend.route("/report/<package_name>/<version>/<job_type>/<job_id>/")
-def report(job_id, package_name="", version="", job_type=""):
-# TODO : design architecture Pending, firewose ?
-# report = Report.load(report_id)
- config = Config()
- session = Session()
- job_query = session.query(Job).filter(Job.id == job_id)
- try:
- job = job_query.one()
- except:
- raise Exception("This resource does not exist")
-
- job_info = {}
- job_info['job'] = job
time_diff = job.finished_at - job.assigned_at
hours, remainder = divmod(time_diff.total_seconds(), 3600)
minutes, seconds = divmod(remainder, 60)
- job_info['job_runtime'] = '%dh %02dm %02ds' % (hours, minutes, seconds)
- job_info['job_runtime_type'] = type(job.finished_at - job.assigned_at)
- job_info['machine_link'] = "/machine/%s" % job.machine.name
- if job.package.type == "source":
- job_info['package_link'] = '/source/%s/%s/%s/%s' % (job.package.user.login, job.package.name, job.package.version, job.package.run)
- else:
- pool = os.path.join(config.get('paths', 'pool_url'), str(job.package.source.package_id), job.package.arch, job.package.deb)
- job_info['deb_link'] = pool
- job_info['source_link'] = '/source/%s/%s/%s/%s' % (job.package.source.user.login, job.package.source.name, job.package.source.version, job.package.source.run)
-
- log_path = os.path.join(config.get('paths', 'jobs_path'),
- job_id, 'log.txt')
- firehose_link = "/static-job-reports/%s/firehose.xml" % job_id
- log_link = "/static-job-reports/%s/log.txt" % job_id
-
- ### SCANDALOUS HACK
- if job.type == 'clanganalyzer':
- scanbuild_link = "/static-job-reports/%s/scan-build/" % job_id
- else:
- scanbuild_link = ""
-
- log = []
- if os.path.exists(log_path):
- log = (x.decode('utf-8') for x in open(log_path, 'r'))
-
- return render_template('report.html', **{
- "job_info": job_info,
- "log_link": log_link,
- "firehose_link": firehose_link,
- "scanbuild_link": scanbuild_link,
- "log": log,
+ info = {}
+ info['job_runtime'] = '%dh %02dm %02ds' % \
+ (hours, minutes, seconds)
+ info['source_link'] = '/source/%s/%s/%s' % \
+ (job.group.name, job.source.name, job.source.version)
+ info['binary_link'] = '/job/%s/%s/%s/%d' % \
+ (job.group.name, job.binary.name, job.binary.version, job.binary.build_job_id) if job.binary else None
+ info['builder_link'] = "/builder/%s" % job.builder.name
+
+ info['dud_name'] = "%d.dud" % job.id
+ info['log_name'] = "%d.log" % job.id
+ info['firehose_name'] = "%d.firehose.xml" % job.id
+ special_files = [info['dud_name'], info['log_name'], info['firehose_name']]
+ info['files'] = sorted([x for x in os.listdir(job.files_path) if x not in special_files])
+
+ return render_template('job.html', **{
+ "job": job,
+ "info": info,
})
- at frontend.route("/report/firehose/<job_id>/")
-def report_firehose(job_id):
- config = Config()
- firehose_path = os.path.join(config.get('paths', 'jobs_path'),
- job_id, 'firehose.xml')
-
- if os.path.exists(firehose_path):
- return send_file(firehose_path, mimetype='application/xml',
- as_attachment=True, attachment_filename='firehose.xml')
-
-
- at frontend.route("/report/log/<job_id>/")
-def report_log(job_id):
- config = Config()
- log_path = os.path.join(config.get('paths', 'jobs_path'),
- job_id, 'log')
-
- if os.path.exists(log_path):
- return send_file(log_path, mimetype='text/plain', as_attachment=True,
- attachment_filename='log.txt')
-
-
- at frontend.route('/_search_package')
-def search_package():
+ at frontend.route('/_search_source')
+def search_source():
search = request.args.get('search[term]')
- session = Session()
- packages_query = session.query(Source.name)\
- .filter(Source.name.startswith(search)).group_by(Source.name).limit(10)
- result = [r[0] for r in packages_query]
+ session = make_session()
+ query = session.query(Source.name)\
+ .filter(Source.name.startswith(search))\
+ .group_by(Source.name).limit(10)
+ result = [r[0] for r in query]
return jsonify(result)
+
@frontend.route('/_search_maintainer')
def search_maintainer():
search = request.args.get('search[term]')
- session = Session()
- print "foo" + search
- maintainers_query = session.query(Source.maintainer)\
- .filter(Source.maintainer.contains(search))\
- .group_by(Source.maintainer).limit(10)
- result = [r[0] for r in maintainers_query]
+ session = make_session()
+ query = session.query(Maintainer.name, Maintainer.email)\
+ .filter(Maintainer.name.startswith(search) |
+ Maintainer.email.startswith(search))\
+ .group_by(Maintainer.name, Maintainer.email).limit(10)
+ result = [r[0] if r[0].startswith(search) else r[1] for r in query]
return jsonify(result)
diff --git a/static/css/jquery-ui.css b/static/css/jquery-ui.css
deleted file mode 100644
index 94cbfca..0000000
--- a/static/css/jquery-ui.css
+++ /dev/null
@@ -1,1175 +0,0 @@
-/*! jQuery UI - v1.10.2 - 2013-03-14
-* http://jqueryui.com
-* Includes: jquery.ui.core.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
-* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Lucida%20Grande%2CLucida%20Sans%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=5px&bgColorHeader=5c9ccc&bgTextureHeader=gloss_wave&bgImgOpacityHeader=55&borderColorHeader=4297d7&fcHeader=ffffff&iconColorHeader=d8e7f3&bgColorContent=fcfdfd&bgTextureContent=inset_hard&bgImgOpacityContent=100&borderColorContent=a6c9e2&fcContent=222222&iconColorContent=469bdd&bgColorDefault=dfeffc&bgTextureDef [...]
-* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
-
-/* Layout helpers
-----------------------------------*/
-.ui-helper-hidden {
- display: none;
-}
-.ui-helper-hidden-accessible {
- border: 0;
- clip: rect(0 0 0 0);
- height: 1px;
- margin: -1px;
- overflow: hidden;
- padding: 0;
- position: absolute;
- width: 1px;
-}
-.ui-helper-reset {
- margin: 0;
- padding: 0;
- border: 0;
- outline: 0;
- line-height: 1.3;
- text-decoration: none;
- font-size: 100%;
- list-style: none;
-}
-.ui-helper-clearfix:before,
-.ui-helper-clearfix:after {
- content: "";
- display: table;
- border-collapse: collapse;
-}
-.ui-helper-clearfix:after {
- clear: both;
-}
-.ui-helper-clearfix {
- min-height: 0; /* support: IE7 */
-}
-.ui-helper-zfix {
- width: 100%;
- height: 100%;
- top: 0;
- left: 0;
- position: absolute;
- opacity: 0;
- filter:Alpha(Opacity=0);
-}
-
-.ui-front {
- z-index: 100;
-}
-
-
-/* Interaction Cues
-----------------------------------*/
-.ui-state-disabled {
- cursor: default !important;
-}
-
-
-/* Icons
-----------------------------------*/
-
-/* states and images */
-.ui-icon {
- display: block;
- text-indent: -99999px;
- overflow: hidden;
- background-repeat: no-repeat;
-}
-
-
-/* Misc visuals
-----------------------------------*/
-
-/* Overlays */
-.ui-widget-overlay {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
-}
-.ui-accordion .ui-accordion-header {
- display: block;
- cursor: pointer;
- position: relative;
- margin-top: 2px;
- padding: .5em .5em .5em .7em;
- min-height: 0; /* support: IE7 */
-}
-.ui-accordion .ui-accordion-icons {
- padding-left: 2.2em;
-}
-.ui-accordion .ui-accordion-noicons {
- padding-left: .7em;
-}
-.ui-accordion .ui-accordion-icons .ui-accordion-icons {
- padding-left: 2.2em;
-}
-.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
- position: absolute;
- left: .5em;
- top: 50%;
- margin-top: -8px;
-}
-.ui-accordion .ui-accordion-content {
- padding: 1em 2.2em;
- border-top: 0;
- overflow: auto;
-}
-.ui-autocomplete {
- position: absolute;
- top: 0;
- left: 0;
- cursor: default;
-}
-.ui-button {
- display: inline-block;
- position: relative;
- padding: 0;
- line-height: normal;
- margin-right: .1em;
- cursor: pointer;
- vertical-align: middle;
- text-align: center;
- overflow: visible; /* removes extra width in IE */
-}
-.ui-button,
-.ui-button:link,
-.ui-button:visited,
-.ui-button:hover,
-.ui-button:active {
- text-decoration: none;
-}
-/* to make room for the icon, a width needs to be set here */
-.ui-button-icon-only {
- width: 2.2em;
-}
-/* button elements seem to need a little more width */
-button.ui-button-icon-only {
- width: 2.4em;
-}
-.ui-button-icons-only {
- width: 3.4em;
-}
-button.ui-button-icons-only {
- width: 3.7em;
-}
-
-/* button text element */
-.ui-button .ui-button-text {
- display: block;
- line-height: normal;
-}
-.ui-button-text-only .ui-button-text {
- padding: .4em 1em;
-}
-.ui-button-icon-only .ui-button-text,
-.ui-button-icons-only .ui-button-text {
- padding: .4em;
- text-indent: -9999999px;
-}
-.ui-button-text-icon-primary .ui-button-text,
-.ui-button-text-icons .ui-button-text {
- padding: .4em 1em .4em 2.1em;
-}
-.ui-button-text-icon-secondary .ui-button-text,
-.ui-button-text-icons .ui-button-text {
- padding: .4em 2.1em .4em 1em;
-}
-.ui-button-text-icons .ui-button-text {
- padding-left: 2.1em;
- padding-right: 2.1em;
-}
-/* no icon support for input elements, provide padding by default */
-input.ui-button {
- padding: .4em 1em;
-}
-
-/* button icon element(s) */
-.ui-button-icon-only .ui-icon,
-.ui-button-text-icon-primary .ui-icon,
-.ui-button-text-icon-secondary .ui-icon,
-.ui-button-text-icons .ui-icon,
-.ui-button-icons-only .ui-icon {
- position: absolute;
- top: 50%;
- margin-top: -8px;
-}
-.ui-button-icon-only .ui-icon {
- left: 50%;
- margin-left: -8px;
-}
-.ui-button-text-icon-primary .ui-button-icon-primary,
-.ui-button-text-icons .ui-button-icon-primary,
-.ui-button-icons-only .ui-button-icon-primary {
- left: .5em;
-}
-.ui-button-text-icon-secondary .ui-button-icon-secondary,
-.ui-button-text-icons .ui-button-icon-secondary,
-.ui-button-icons-only .ui-button-icon-secondary {
- right: .5em;
-}
-
-/* button sets */
-.ui-buttonset {
- margin-right: 7px;
-}
-.ui-buttonset .ui-button {
- margin-left: 0;
- margin-right: -.3em;
-}
-
-/* workarounds */
-/* reset extra padding in Firefox, see h5bp.com/l */
-input.ui-button::-moz-focus-inner,
-button.ui-button::-moz-focus-inner {
- border: 0;
- padding: 0;
-}
-.ui-datepicker {
- width: 17em;
- padding: .2em .2em 0;
- display: none;
-}
-.ui-datepicker .ui-datepicker-header {
- position: relative;
- padding: .2em 0;
-}
-.ui-datepicker .ui-datepicker-prev,
-.ui-datepicker .ui-datepicker-next {
- position: absolute;
- top: 2px;
- width: 1.8em;
- height: 1.8em;
-}
-.ui-datepicker .ui-datepicker-prev-hover,
-.ui-datepicker .ui-datepicker-next-hover {
- top: 1px;
-}
-.ui-datepicker .ui-datepicker-prev {
- left: 2px;
-}
-.ui-datepicker .ui-datepicker-next {
- right: 2px;
-}
-.ui-datepicker .ui-datepicker-prev-hover {
- left: 1px;
-}
-.ui-datepicker .ui-datepicker-next-hover {
- right: 1px;
-}
-.ui-datepicker .ui-datepicker-prev span,
-.ui-datepicker .ui-datepicker-next span {
- display: block;
- position: absolute;
- left: 50%;
- margin-left: -8px;
- top: 50%;
- margin-top: -8px;
-}
-.ui-datepicker .ui-datepicker-title {
- margin: 0 2.3em;
- line-height: 1.8em;
- text-align: center;
-}
-.ui-datepicker .ui-datepicker-title select {
- font-size: 1em;
- margin: 1px 0;
-}
-.ui-datepicker select.ui-datepicker-month-year {
- width: 100%;
-}
-.ui-datepicker select.ui-datepicker-month,
-.ui-datepicker select.ui-datepicker-year {
- width: 49%;
-}
-.ui-datepicker table {
- width: 100%;
- font-size: .9em;
- border-collapse: collapse;
- margin: 0 0 .4em;
-}
-.ui-datepicker th {
- padding: .7em .3em;
- text-align: center;
- font-weight: bold;
- border: 0;
-}
-.ui-datepicker td {
- border: 0;
- padding: 1px;
-}
-.ui-datepicker td span,
-.ui-datepicker td a {
- display: block;
- padding: .2em;
- text-align: right;
- text-decoration: none;
-}
-.ui-datepicker .ui-datepicker-buttonpane {
- background-image: none;
- margin: .7em 0 0 0;
- padding: 0 .2em;
- border-left: 0;
- border-right: 0;
- border-bottom: 0;
-}
-.ui-datepicker .ui-datepicker-buttonpane button {
- float: right;
- margin: .5em .2em .4em;
- cursor: pointer;
- padding: .2em .6em .3em .6em;
- width: auto;
- overflow: visible;
-}
-.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
- float: left;
-}
-
-/* with multiple calendars */
-.ui-datepicker.ui-datepicker-multi {
- width: auto;
-}
-.ui-datepicker-multi .ui-datepicker-group {
- float: left;
-}
-.ui-datepicker-multi .ui-datepicker-group table {
- width: 95%;
- margin: 0 auto .4em;
-}
-.ui-datepicker-multi-2 .ui-datepicker-group {
- width: 50%;
-}
-.ui-datepicker-multi-3 .ui-datepicker-group {
- width: 33.3%;
-}
-.ui-datepicker-multi-4 .ui-datepicker-group {
- width: 25%;
-}
-.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
-.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
- border-left-width: 0;
-}
-.ui-datepicker-multi .ui-datepicker-buttonpane {
- clear: left;
-}
-.ui-datepicker-row-break {
- clear: both;
- width: 100%;
- font-size: 0;
-}
-
-/* RTL support */
-.ui-datepicker-rtl {
- direction: rtl;
-}
-.ui-datepicker-rtl .ui-datepicker-prev {
- right: 2px;
- left: auto;
-}
-.ui-datepicker-rtl .ui-datepicker-next {
- left: 2px;
- right: auto;
-}
-.ui-datepicker-rtl .ui-datepicker-prev:hover {
- right: 1px;
- left: auto;
-}
-.ui-datepicker-rtl .ui-datepicker-next:hover {
- left: 1px;
- right: auto;
-}
-.ui-datepicker-rtl .ui-datepicker-buttonpane {
- clear: right;
-}
-.ui-datepicker-rtl .ui-datepicker-buttonpane button {
- float: left;
-}
-.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
-.ui-datepicker-rtl .ui-datepicker-group {
- float: right;
-}
-.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
-.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
- border-right-width: 0;
- border-left-width: 1px;
-}
-.ui-dialog {
- position: absolute;
- top: 0;
- left: 0;
- padding: .2em;
- outline: 0;
-}
-.ui-dialog .ui-dialog-titlebar {
- padding: .4em 1em;
- position: relative;
-}
-.ui-dialog .ui-dialog-title {
- float: left;
- margin: .1em 0;
- white-space: nowrap;
- width: 90%;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-.ui-dialog .ui-dialog-titlebar-close {
- position: absolute;
- right: .3em;
- top: 50%;
- width: 21px;
- margin: -10px 0 0 0;
- padding: 1px;
- height: 20px;
-}
-.ui-dialog .ui-dialog-content {
- position: relative;
- border: 0;
- padding: .5em 1em;
- background: none;
- overflow: auto;
-}
-.ui-dialog .ui-dialog-buttonpane {
- text-align: left;
- border-width: 1px 0 0 0;
- background-image: none;
- margin-top: .5em;
- padding: .3em 1em .5em .4em;
-}
-.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
- float: right;
-}
-.ui-dialog .ui-dialog-buttonpane button {
- margin: .5em .4em .5em 0;
- cursor: pointer;
-}
-.ui-dialog .ui-resizable-se {
- width: 12px;
- height: 12px;
- right: -5px;
- bottom: -5px;
- background-position: 16px 16px;
-}
-.ui-draggable .ui-dialog-titlebar {
- cursor: move;
-}
-.ui-menu {
- list-style: none;
- padding: 2px;
- margin: 0;
- display: block;
- outline: none;
-}
-.ui-menu .ui-menu {
- margin-top: -3px;
- position: absolute;
-}
-.ui-menu .ui-menu-item {
- margin: 0;
- padding: 0;
- width: 100%;
-}
-.ui-menu .ui-menu-divider {
- margin: 5px -2px 5px -2px;
- height: 0;
- font-size: 0;
- line-height: 0;
- border-width: 1px 0 0 0;
-}
-.ui-menu .ui-menu-item a {
- text-decoration: none;
- display: block;
- padding: 2px .4em;
- line-height: 1.5;
- min-height: 0; /* support: IE7 */
- font-weight: normal;
-}
-.ui-menu .ui-menu-item a.ui-state-focus,
-.ui-menu .ui-menu-item a.ui-state-active {
- font-weight: normal;
- margin: -1px;
-}
-
-.ui-menu .ui-state-disabled {
- font-weight: normal;
- margin: .4em 0 .2em;
- line-height: 1.5;
-}
-.ui-menu .ui-state-disabled a {
- cursor: default;
-}
-
-/* icon support */
-.ui-menu-icons {
- position: relative;
-}
-.ui-menu-icons .ui-menu-item a {
- position: relative;
- padding-left: 2em;
-}
-
-/* left-aligned */
-.ui-menu .ui-icon {
- position: absolute;
- top: .2em;
- left: .2em;
-}
-
-/* right-aligned */
-.ui-menu .ui-menu-icon {
- position: static;
- float: right;
-}
-.ui-progressbar {
- height: 2em;
- text-align: left;
- overflow: hidden;
-}
-.ui-progressbar .ui-progressbar-value {
- margin: -1px;
- height: 100%;
-}
-.ui-progressbar .ui-progressbar-overlay {
- background: url("images/animated-overlay.gif");
- height: 100%;
- filter: alpha(opacity=25);
- opacity: 0.25;
-}
-.ui-progressbar-indeterminate .ui-progressbar-value {
- background-image: none;
-}
-.ui-resizable {
- position: relative;
-}
-.ui-resizable-handle {
- position: absolute;
- font-size: 0.1px;
- display: block;
-}
-.ui-resizable-disabled .ui-resizable-handle,
-.ui-resizable-autohide .ui-resizable-handle {
- display: none;
-}
-.ui-resizable-n {
- cursor: n-resize;
- height: 7px;
- width: 100%;
- top: -5px;
- left: 0;
-}
-.ui-resizable-s {
- cursor: s-resize;
- height: 7px;
- width: 100%;
- bottom: -5px;
- left: 0;
-}
-.ui-resizable-e {
- cursor: e-resize;
- width: 7px;
- right: -5px;
- top: 0;
- height: 100%;
-}
-.ui-resizable-w {
- cursor: w-resize;
- width: 7px;
- left: -5px;
- top: 0;
- height: 100%;
-}
-.ui-resizable-se {
- cursor: se-resize;
- width: 12px;
- height: 12px;
- right: 1px;
- bottom: 1px;
-}
-.ui-resizable-sw {
- cursor: sw-resize;
- width: 9px;
- height: 9px;
- left: -5px;
- bottom: -5px;
-}
-.ui-resizable-nw {
- cursor: nw-resize;
- width: 9px;
- height: 9px;
- left: -5px;
- top: -5px;
-}
-.ui-resizable-ne {
- cursor: ne-resize;
- width: 9px;
- height: 9px;
- right: -5px;
- top: -5px;
-}
-.ui-selectable-helper {
- position: absolute;
- z-index: 100;
- border: 1px dotted black;
-}
-.ui-slider {
- position: relative;
- text-align: left;
-}
-.ui-slider .ui-slider-handle {
- position: absolute;
- z-index: 2;
- width: 1.2em;
- height: 1.2em;
- cursor: default;
-}
-.ui-slider .ui-slider-range {
- position: absolute;
- z-index: 1;
- font-size: .7em;
- display: block;
- border: 0;
- background-position: 0 0;
-}
-
-/* For IE8 - See #6727 */
-.ui-slider.ui-state-disabled .ui-slider-handle,
-.ui-slider.ui-state-disabled .ui-slider-range {
- filter: inherit;
-}
-
-.ui-slider-horizontal {
- height: .8em;
-}
-.ui-slider-horizontal .ui-slider-handle {
- top: -.3em;
- margin-left: -.6em;
-}
-.ui-slider-horizontal .ui-slider-range {
- top: 0;
- height: 100%;
-}
-.ui-slider-horizontal .ui-slider-range-min {
- left: 0;
-}
-.ui-slider-horizontal .ui-slider-range-max {
- right: 0;
-}
-
-.ui-slider-vertical {
- width: .8em;
- height: 100px;
-}
-.ui-slider-vertical .ui-slider-handle {
- left: -.3em;
- margin-left: 0;
- margin-bottom: -.6em;
-}
-.ui-slider-vertical .ui-slider-range {
- left: 0;
- width: 100%;
-}
-.ui-slider-vertical .ui-slider-range-min {
- bottom: 0;
-}
-.ui-slider-vertical .ui-slider-range-max {
- top: 0;
-}
-.ui-spinner {
- position: relative;
- display: inline-block;
- overflow: hidden;
- padding: 0;
- vertical-align: middle;
-}
-.ui-spinner-input {
- border: none;
- background: none;
- color: inherit;
- padding: 0;
- margin: .2em 0;
- vertical-align: middle;
- margin-left: .4em;
- margin-right: 22px;
-}
-.ui-spinner-button {
- width: 16px;
- height: 50%;
- font-size: .5em;
- padding: 0;
- margin: 0;
- text-align: center;
- position: absolute;
- cursor: default;
- display: block;
- overflow: hidden;
- right: 0;
-}
-/* more specificity required here to overide default borders */
-.ui-spinner a.ui-spinner-button {
- border-top: none;
- border-bottom: none;
- border-right: none;
-}
-/* vertical centre icon */
-.ui-spinner .ui-icon {
- position: absolute;
- margin-top: -8px;
- top: 50%;
- left: 0;
-}
-.ui-spinner-up {
- top: 0;
-}
-.ui-spinner-down {
- bottom: 0;
-}
-
-/* TR overrides */
-.ui-spinner .ui-icon-triangle-1-s {
- /* need to fix icons sprite */
- background-position: -65px -16px;
-}
-.ui-tabs {
- position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
- padding: .2em;
-}
-.ui-tabs .ui-tabs-nav {
- margin: 0;
- padding: .2em .2em 0;
-}
-.ui-tabs .ui-tabs-nav li {
- list-style: none;
- float: left;
- position: relative;
- top: 0;
- margin: 1px .2em 0 0;
- border-bottom-width: 0;
- padding: 0;
- white-space: nowrap;
-}
-.ui-tabs .ui-tabs-nav li a {
- float: left;
- padding: .5em 1em;
- text-decoration: none;
-}
-.ui-tabs .ui-tabs-nav li.ui-tabs-active {
- margin-bottom: -1px;
- padding-bottom: 1px;
-}
-.ui-tabs .ui-tabs-nav li.ui-tabs-active a,
-.ui-tabs .ui-tabs-nav li.ui-state-disabled a,
-.ui-tabs .ui-tabs-nav li.ui-tabs-loading a {
- cursor: text;
-}
-.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
-.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a {
- cursor: pointer;
-}
-.ui-tabs .ui-tabs-panel {
- display: block;
- border-width: 0;
- padding: 1em 1.4em;
- background: none;
-}
-.ui-tooltip {
- padding: 8px;
- position: absolute;
- z-index: 9999;
- max-width: 300px;
- -webkit-box-shadow: 0 0 5px #aaa;
- box-shadow: 0 0 5px #aaa;
-}
-body .ui-tooltip {
- border-width: 2px;
-}
-
-/* Component containers
-----------------------------------*/
-.ui-widget {
- font-family: Lucida Grande,Lucida Sans,Arial,sans-serif;
- font-size: 1.1em;
-}
-.ui-widget .ui-widget {
- font-size: 1em;
-}
-.ui-widget input,
-.ui-widget select,
-.ui-widget textarea,
-.ui-widget button {
-/* font-family: Lucida Grande,Lucida Sans,Arial,sans-serif;
- font-size: 1em;*/
-}
-.ui-widget-content {
- border: 1px solid #a6c9e2;
- background: #fcfdfd url(images/ui-bg_inset-hard_100_fcfdfd_1x100.png) 50% bottom repeat-x;
- color: #222222;
-}
-.ui-widget-content a {
- color: #222222;
-}
-.ui-widget-header {
- border: 1px solid #4297d7;
- background: #5c9ccc url(images/ui-bg_gloss-wave_55_5c9ccc_500x100.png) 50% 50% repeat-x;
- color: #ffffff;
- font-weight: bold;
-}
-.ui-widget-header a {
- color: #ffffff;
-}
-
-/* Interaction states
-----------------------------------*/
-.ui-state-default,
-.ui-widget-content .ui-state-default,
-.ui-widget-header .ui-state-default {
- border: 1px solid #c5dbec;
- background: #dfeffc url(images/ui-bg_glass_85_dfeffc_1x400.png) 50% 50% repeat-x;
- font-weight: bold;
- color: #2e6e9e;
-}
-.ui-state-default a,
-.ui-state-default a:link,
-.ui-state-default a:visited {
- color: #2e6e9e;
- text-decoration: none;
-}
-.ui-state-hover,
-.ui-widget-content .ui-state-hover,
-.ui-widget-header .ui-state-hover,
-.ui-state-focus,
-.ui-widget-content .ui-state-focus,
-.ui-widget-header .ui-state-focus {
- border: 1px solid #79b7e7;
- background: #d0e5f5 url(images/ui-bg_glass_75_d0e5f5_1x400.png) 50% 50% repeat-x;
- font-weight: bold;
- color: #1d5987;
-}
-.ui-state-hover a,
-.ui-state-hover a:hover,
-.ui-state-hover a:link,
-.ui-state-hover a:visited {
- color: #1d5987;
- text-decoration: none;
-}
-.ui-state-active,
-.ui-widget-content .ui-state-active,
-.ui-widget-header .ui-state-active {
- border: 1px solid #79b7e7;
- background: #f5f8f9 url(images/ui-bg_inset-hard_100_f5f8f9_1x100.png) 50% 50% repeat-x;
- font-weight: bold;
- color: #e17009;
-}
-.ui-state-active a,
-.ui-state-active a:link,
-.ui-state-active a:visited {
- color: #e17009;
- text-decoration: none;
-}
-
-/* Interaction Cues
-----------------------------------*/
-.ui-state-highlight,
-.ui-widget-content .ui-state-highlight,
-.ui-widget-header .ui-state-highlight {
- border: 1px solid #fad42e;
- background: #fbec88 url(images/ui-bg_flat_55_fbec88_40x100.png) 50% 50% repeat-x;
- color: #363636;
-}
-.ui-state-highlight a,
-.ui-widget-content .ui-state-highlight a,
-.ui-widget-header .ui-state-highlight a {
- color: #363636;
-}
-.ui-state-error,
-.ui-widget-content .ui-state-error,
-.ui-widget-header .ui-state-error {
- border: 1px solid #cd0a0a;
- background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x;
- color: #cd0a0a;
-}
-.ui-state-error a,
-.ui-widget-content .ui-state-error a,
-.ui-widget-header .ui-state-error a {
- color: #cd0a0a;
-}
-.ui-state-error-text,
-.ui-widget-content .ui-state-error-text,
-.ui-widget-header .ui-state-error-text {
- color: #cd0a0a;
-}
-.ui-priority-primary,
-.ui-widget-content .ui-priority-primary,
-.ui-widget-header .ui-priority-primary {
- font-weight: bold;
-}
-.ui-priority-secondary,
-.ui-widget-content .ui-priority-secondary,
-.ui-widget-header .ui-priority-secondary {
- opacity: .7;
- filter:Alpha(Opacity=70);
- font-weight: normal;
-}
-.ui-state-disabled,
-.ui-widget-content .ui-state-disabled,
-.ui-widget-header .ui-state-disabled {
- opacity: .35;
- filter:Alpha(Opacity=35);
- background-image: none;
-}
-.ui-state-disabled .ui-icon {
- filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
-}
-
-/* Icons
-----------------------------------*/
-
-/* states and images */
-.ui-icon {
- width: 16px;
- height: 16px;
-}
-.ui-icon,
-.ui-widget-content .ui-icon {
- background-image: url(images/ui-icons_469bdd_256x240.png);
-}
-.ui-widget-header .ui-icon {
- background-image: url(images/ui-icons_d8e7f3_256x240.png);
-}
-.ui-state-default .ui-icon {
- background-image: url(images/ui-icons_6da8d5_256x240.png);
-}
-.ui-state-hover .ui-icon,
-.ui-state-focus .ui-icon {
- background-image: url(images/ui-icons_217bc0_256x240.png);
-}
-.ui-state-active .ui-icon {
- background-image: url(images/ui-icons_f9bd01_256x240.png);
-}
-.ui-state-highlight .ui-icon {
- background-image: url(images/ui-icons_2e83ff_256x240.png);
-}
-.ui-state-error .ui-icon,
-.ui-state-error-text .ui-icon {
- background-image: url(images/ui-icons_cd0a0a_256x240.png);
-}
-
-/* positioning */
-.ui-icon-blank { background-position: 16px 16px; }
-.ui-icon-carat-1-n { background-position: 0 0; }
-.ui-icon-carat-1-ne { background-position: -16px 0; }
-.ui-icon-carat-1-e { background-position: -32px 0; }
-.ui-icon-carat-1-se { background-position: -48px 0; }
-.ui-icon-carat-1-s { background-position: -64px 0; }
-.ui-icon-carat-1-sw { background-position: -80px 0; }
-.ui-icon-carat-1-w { background-position: -96px 0; }
-.ui-icon-carat-1-nw { background-position: -112px 0; }
-.ui-icon-carat-2-n-s { background-position: -128px 0; }
-.ui-icon-carat-2-e-w { background-position: -144px 0; }
-.ui-icon-triangle-1-n { background-position: 0 -16px; }
-.ui-icon-triangle-1-ne { background-position: -16px -16px; }
-.ui-icon-triangle-1-e { background-position: -32px -16px; }
-.ui-icon-triangle-1-se { background-position: -48px -16px; }
-.ui-icon-triangle-1-s { background-position: -64px -16px; }
-.ui-icon-triangle-1-sw { background-position: -80px -16px; }
-.ui-icon-triangle-1-w { background-position: -96px -16px; }
-.ui-icon-triangle-1-nw { background-position: -112px -16px; }
-.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
-.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
-.ui-icon-arrow-1-n { background-position: 0 -32px; }
-.ui-icon-arrow-1-ne { background-position: -16px -32px; }
-.ui-icon-arrow-1-e { background-position: -32px -32px; }
-.ui-icon-arrow-1-se { background-position: -48px -32px; }
-.ui-icon-arrow-1-s { background-position: -64px -32px; }
-.ui-icon-arrow-1-sw { background-position: -80px -32px; }
-.ui-icon-arrow-1-w { background-position: -96px -32px; }
-.ui-icon-arrow-1-nw { background-position: -112px -32px; }
-.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
-.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
-.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
-.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
-.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
-.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
-.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
-.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
-.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
-.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
-.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
-.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
-.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
-.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
-.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
-.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
-.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
-.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
-.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
-.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
-.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
-.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
-.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
-.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
-.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
-.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
-.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
-.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
-.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
-.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
-.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
-.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
-.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
-.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
-.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
-.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
-.ui-icon-arrow-4 { background-position: 0 -80px; }
-.ui-icon-arrow-4-diag { background-position: -16px -80px; }
-.ui-icon-extlink { background-position: -32px -80px; }
-.ui-icon-newwin { background-position: -48px -80px; }
-.ui-icon-refresh { background-position: -64px -80px; }
-.ui-icon-shuffle { background-position: -80px -80px; }
-.ui-icon-transfer-e-w { background-position: -96px -80px; }
-.ui-icon-transferthick-e-w { background-position: -112px -80px; }
-.ui-icon-folder-collapsed { background-position: 0 -96px; }
-.ui-icon-folder-open { background-position: -16px -96px; }
-.ui-icon-document { background-position: -32px -96px; }
-.ui-icon-document-b { background-position: -48px -96px; }
-.ui-icon-note { background-position: -64px -96px; }
-.ui-icon-mail-closed { background-position: -80px -96px; }
-.ui-icon-mail-open { background-position: -96px -96px; }
-.ui-icon-suitcase { background-position: -112px -96px; }
-.ui-icon-comment { background-position: -128px -96px; }
-.ui-icon-person { background-position: -144px -96px; }
-.ui-icon-print { background-position: -160px -96px; }
-.ui-icon-trash { background-position: -176px -96px; }
-.ui-icon-locked { background-position: -192px -96px; }
-.ui-icon-unlocked { background-position: -208px -96px; }
-.ui-icon-bookmark { background-position: -224px -96px; }
-.ui-icon-tag { background-position: -240px -96px; }
-.ui-icon-home { background-position: 0 -112px; }
-.ui-icon-flag { background-position: -16px -112px; }
-.ui-icon-calendar { background-position: -32px -112px; }
-.ui-icon-cart { background-position: -48px -112px; }
-.ui-icon-pencil { background-position: -64px -112px; }
-.ui-icon-clock { background-position: -80px -112px; }
-.ui-icon-disk { background-position: -96px -112px; }
-.ui-icon-calculator { background-position: -112px -112px; }
-.ui-icon-zoomin { background-position: -128px -112px; }
-.ui-icon-zoomout { background-position: -144px -112px; }
-.ui-icon-search { background-position: -160px -112px; }
-.ui-icon-wrench { background-position: -176px -112px; }
-.ui-icon-gear { background-position: -192px -112px; }
-.ui-icon-heart { background-position: -208px -112px; }
-.ui-icon-star { background-position: -224px -112px; }
-.ui-icon-link { background-position: -240px -112px; }
-.ui-icon-cancel { background-position: 0 -128px; }
-.ui-icon-plus { background-position: -16px -128px; }
-.ui-icon-plusthick { background-position: -32px -128px; }
-.ui-icon-minus { background-position: -48px -128px; }
-.ui-icon-minusthick { background-position: -64px -128px; }
-.ui-icon-close { background-position: -80px -128px; }
-.ui-icon-closethick { background-position: -96px -128px; }
-.ui-icon-key { background-position: -112px -128px; }
-.ui-icon-lightbulb { background-position: -128px -128px; }
-.ui-icon-scissors { background-position: -144px -128px; }
-.ui-icon-clipboard { background-position: -160px -128px; }
-.ui-icon-copy { background-position: -176px -128px; }
-.ui-icon-contact { background-position: -192px -128px; }
-.ui-icon-image { background-position: -208px -128px; }
-.ui-icon-video { background-position: -224px -128px; }
-.ui-icon-script { background-position: -240px -128px; }
-.ui-icon-alert { background-position: 0 -144px; }
-.ui-icon-info { background-position: -16px -144px; }
-.ui-icon-notice { background-position: -32px -144px; }
-.ui-icon-help { background-position: -48px -144px; }
-.ui-icon-check { background-position: -64px -144px; }
-.ui-icon-bullet { background-position: -80px -144px; }
-.ui-icon-radio-on { background-position: -96px -144px; }
-.ui-icon-radio-off { background-position: -112px -144px; }
-.ui-icon-pin-w { background-position: -128px -144px; }
-.ui-icon-pin-s { background-position: -144px -144px; }
-.ui-icon-play { background-position: 0 -160px; }
-.ui-icon-pause { background-position: -16px -160px; }
-.ui-icon-seek-next { background-position: -32px -160px; }
-.ui-icon-seek-prev { background-position: -48px -160px; }
-.ui-icon-seek-end { background-position: -64px -160px; }
-.ui-icon-seek-start { background-position: -80px -160px; }
-/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
-.ui-icon-seek-first { background-position: -80px -160px; }
-.ui-icon-stop { background-position: -96px -160px; }
-.ui-icon-eject { background-position: -112px -160px; }
-.ui-icon-volume-off { background-position: -128px -160px; }
-.ui-icon-volume-on { background-position: -144px -160px; }
-.ui-icon-power { background-position: 0 -176px; }
-.ui-icon-signal-diag { background-position: -16px -176px; }
-.ui-icon-signal { background-position: -32px -176px; }
-.ui-icon-battery-0 { background-position: -48px -176px; }
-.ui-icon-battery-1 { background-position: -64px -176px; }
-.ui-icon-battery-2 { background-position: -80px -176px; }
-.ui-icon-battery-3 { background-position: -96px -176px; }
-.ui-icon-circle-plus { background-position: 0 -192px; }
-.ui-icon-circle-minus { background-position: -16px -192px; }
-.ui-icon-circle-close { background-position: -32px -192px; }
-.ui-icon-circle-triangle-e { background-position: -48px -192px; }
-.ui-icon-circle-triangle-s { background-position: -64px -192px; }
-.ui-icon-circle-triangle-w { background-position: -80px -192px; }
-.ui-icon-circle-triangle-n { background-position: -96px -192px; }
-.ui-icon-circle-arrow-e { background-position: -112px -192px; }
-.ui-icon-circle-arrow-s { background-position: -128px -192px; }
-.ui-icon-circle-arrow-w { background-position: -144px -192px; }
-.ui-icon-circle-arrow-n { background-position: -160px -192px; }
-.ui-icon-circle-zoomin { background-position: -176px -192px; }
-.ui-icon-circle-zoomout { background-position: -192px -192px; }
-.ui-icon-circle-check { background-position: -208px -192px; }
-.ui-icon-circlesmall-plus { background-position: 0 -208px; }
-.ui-icon-circlesmall-minus { background-position: -16px -208px; }
-.ui-icon-circlesmall-close { background-position: -32px -208px; }
-.ui-icon-squaresmall-plus { background-position: -48px -208px; }
-.ui-icon-squaresmall-minus { background-position: -64px -208px; }
-.ui-icon-squaresmall-close { background-position: -80px -208px; }
-.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
-.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
-.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
-.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
-.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
-.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
-
-
-/* Misc visuals
-----------------------------------*/
-
-/* Corner radius */
-.ui-corner-all,
-.ui-corner-top,
-.ui-corner-left,
-.ui-corner-tl {
- border-top-left-radius: 5px;
-}
-.ui-corner-all,
-.ui-corner-top,
-.ui-corner-right,
-.ui-corner-tr {
- border-top-right-radius: 5px;
-}
-.ui-corner-all,
-.ui-corner-bottom,
-.ui-corner-left,
-.ui-corner-bl {
- border-bottom-left-radius: 5px;
-}
-.ui-corner-all,
-.ui-corner-bottom,
-.ui-corner-right,
-.ui-corner-br {
- border-bottom-right-radius: 5px;
-}
-
-/* Overlays */
-.ui-widget-overlay {
- background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;
- opacity: .3;
- filter: Alpha(Opacity=30);
-}
-.ui-widget-shadow {
- margin: -8px 0 0 -8px;
- padding: 8px;
- background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;
- opacity: .3;
- filter: Alpha(Opacity=30);
- border-radius: 8px;
-}
diff --git a/templates/builder.html b/templates/builder.html
new file mode 100644
index 0000000..bf1f1ca
--- /dev/null
+++ b/templates/builder.html
@@ -0,0 +1,36 @@
+{% extends "base.html" %}
+
+{% block title %}{{builder.name}}{% endblock %}
+
+{% block content %}
+ <h1>{{builder.name}}</h1>
+ <div class='block'>
+ <div class='desc_line'>
+ <div class='desc_key'>Name</div>
+ <div class='desc_value'>{{builder.name}}</div>
+ </div>
+ <div class='desc_line'>
+ <div class='desc_key'>Maintainer</div>
+ <div class='desc_value'><a href='{{info.maintainer_link}}'>{{builder.maintainer.name}}</a></div>
+ </div>
+ <div class='desc_line'>
+ <div class='desc_key'>PGP Fingerprint</div>
+ <div class='desc_value'>{{builder.pgp}}</div>
+ </div>
+ <div class='desc_line'>
+ <div class='desc_key'>SSL Fingerprint</div>
+ <div class='desc_value'>{{builder.ssl}}</div>
+ </div>
+ <div class='desc_line'>
+ <div class='desc_key'>Last Ping</div>
+ <div class='desc_value'>{{machine.last_ping|ago}}</div>
+ </div>
+ </div>
+
+ <h3>Jobs Assigned to {{builder.name}}</h3>
+ {% if info.prev_link %}<a class='left' href='{{info.prev_link}}'>previous page</a>{% endif %}
+ {% if info.next_link %}<a class='right' href='{{info.next_link}}'>next page</a>{% endif %}
+ <div class = 'clear' ></div>
+ {% include "job_list_fragment.html" %}
+
+{% endblock %}
diff --git a/templates/builder_list_fragment.html b/templates/builder_list_fragment.html
new file mode 100644
index 0000000..86e49a7
--- /dev/null
+++ b/templates/builder_list_fragment.html
@@ -0,0 +1,37 @@
+ <table class = 'zebra'>
+ <tr>
+ <th>Name</th>
+ <th>Maintainer</th>
+ <th>Last Ping</th>
+ <th>Current Jobs</th>
+ </tr>
+
+{% for info in builders_info %}
+ <tr>
+ <td>
+ <a href='{{info.builder_link}}'>{{info.builder.name}}</a>
+ </td>
+ <td>
+ {% if info.maintainer_link %}
+ <a href='{{info.maintainer_link}}'>{{info.builder.maintainer.name}}</a>
+ {% else %}
+ {{info.builder.maintainer.name}}
+ {% endif %}
+ </td>
+ <td>
+ {{info.builder.last_ping|ago}}
+ </td>
+ <td>
+ {% if info.jobs_info %}
+ {% for jobinfo in info.jobs_info %}
+ <a href='{{jobinfo.source_link}}'>{{jobinfo.job.source.name}}/{{jobinfo.job.source.version}}</a>
+ <a href='{{jobinfo.job_link}}'>{{jobinfo.job.name}}</a><br />
+ {% endfor %}
+ {% else %}
+ None-Assigned
+ {% endif %}
+ </td>
+ </tr>
+{% endfor %}
+
+ </table>
diff --git a/templates/group.html b/templates/group.html
index 53fb5e5..534af39 100644
--- a/templates/group.html
+++ b/templates/group.html
@@ -1,13 +1,58 @@
{% extends "base.html" %}
-{% block title %}Package List{% endblock %}
+{% block title %}Package Group {{group.name}}{% endblock %}
{% block content %}
-<h1>Package Group {{group_id}}</h1>
-{% if page > 0 %}
- <a class = 'left' href = '/group/{{group_id}}/{{page - 1}}' >last page</a>
-{% endif %}
- <a class = 'right' href = '/group/{{group_id}}/{{page + 1}}' >next page</a>
+ <h1>Package Group {{group.name}}</h1>
+ <div class='block'>
+ <div class='desc_line'>
+ <div class='desc_key'>Maintainer</div>
+ <div class='desc_value'><a href='{{info.maintainer_link}}'>{{group.maintainer.name}}</a></div>
+ </div>
+ <div class='desc_line'>
+ <div class='desc_key'>Repository</div>
+ <div class='desc_value'><a href='{{group.repo_url}}'>{{group.repo_url}}</a></div>
+ </div>
+ <div class='desc_line'>
+ <div class='desc_key'>Suites:</div>
+ <div class='desc_value'>
+ {% for gs in group.suites %}
+ {{gs.suite.name}}
+ {% endfor %}
+ </div>
+ </div>
+ {% for gs in group.suites %}
+ <div class='desc_line'>
+ <div class='desc_key'>{{gs.suite.name}} Components</div>
+ <div class='desc_value'>
+ {% for component in gs.components %}
+ {{component.name}}
+ {% endfor %}
+ </div>
+ </div>
+ <div class='desc_line'>
+ <div class='desc_key'>{{gs.suite.name}} Architectures</div>
+ <div class='desc_value'>
+ {% for arch in gs.arches %}
+ {{arch.name}}
+ {% endfor %}
+ </div>
+ </div>
+ <div class='desc_line'>
+ <div class='desc_key'>{{gs.suite.name}} Checks</div>
+ <div class='desc_value'>
+ {% for check in gs.checks %}
+ {{check.name}}
+ {% endfor %}
+ </div>
+ </div>
+ {% endfor %}
+ </div>
+
+ <h3>Sources in Package Group {{grop.name}}</h3>
+ {% if info.prev_link %}<a class='left' href='{{info.prev_link}}'>previous page</a>{% endif %}
+ {% if info.next_link %}<a class='right' href='{{info.next_link}}'>next page</a>{% endif %}
<div class = 'clear' ></div>
{% include "source_list_fragment.html" %}
+
{% endblock %}
diff --git a/templates/group_list_fragment.html b/templates/group_list_fragment.html
new file mode 100644
index 0000000..b2ee118
--- /dev/null
+++ b/templates/group_list_fragment.html
@@ -0,0 +1,28 @@
+ <table class = 'zebra'>
+ <tr>
+ <th>Group Name</th>
+ <th>Suites</th>
+ <th>Maintainer</th>
+ </tr>
+
+{% for info in groups_info %}
+ <tr>
+ <td>
+ <a href='{{info.group_link}}'>{{info.group.name}}</a>
+ </td>
+ <td>
+ {% for gs in info.group.suites %}
+ {{gs.suite.name}}
+ {% endfor %}
+ </td>
+ <td>
+ {% if info.maintainer_link %}
+ <a href='{{info.maintainer_link}}'>{{info.group.maintainer.name}}</a>
+ {% else %}
+ {{info.group.maintainer.name}}
+ {% endif %}
+ </td>
+ </tr>
+{% endfor %}
+
+ </table>
diff --git a/templates/index.html b/templates/index.html
index e35b324..911e38e 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -1,31 +1,29 @@
{% extends "base.html" %}
-{% import "macros.inc.html" as macros %}
-
-{% block title %}About{% endblock %}
+{% block title %}Debile Web{% endblock %}
{% block content %}
+<h1>Groups</h1>
+{% include "group_list_fragment.html" %}
-This experimental infrastructure aims to provide a generic rebuild platform.<br />
-Normal build, custom builds (clang based) or static analyzers (coccinelle, scan-build, etc) are managed through this infrastructure.<br /><br />
-
-<b>Work in progress</b>
-{% include "search.html" %}
-<br />
-
-<h1>Active Jobs</h1>
+<h1>Builders</h1>
+{% include "builder_list_fragment.html" %}
- {% include "job_list_fragment.html" %}
-
-<h1>Pending jobs</h1><br />
+<h1>Jobs</h1>
+List all <a href='/jobs/incomplete'>incomplete jobs</a><br />
+List all <a href='/jobs/recent'>recent jobs</a><br />
There are currently {{pending_jobs}} jobs to assign.<br />
-<br />
-Browse by prefix:
-{{ macros.render_packages_prefixes(packages_prefixes) }}
-<br />
-<br />Last
-<a href = '/sources' >uploads</a>
+<h1>Sources</h1>
+List all <a href='/sources/incomplete'>incomplete uploads</a><br />
+List all <a href='/sources/recent'>recent uploads</a><br />
+
+<h3>Browse Sources by Prefix:</h3>
+{% for prefix in prefixes %}
+ <a href="/sources/{{prefix}}">{{prefix}}</a>
+{% endfor %}
+<h3>Search Sources</h3>
+{% include "search.html" %}
{% endblock %}
diff --git a/templates/job.html b/templates/job.html
new file mode 100644
index 0000000..6a0ba8c
--- /dev/null
+++ b/templates/job.html
@@ -0,0 +1,103 @@
+{% extends "base.html" %}
+
+{% block title %}{{job.source.name}}/{{job.source.version}} {{job.name}}{% endblock %}
+
+{% block content %}
+
+ <div class='block'>
+ <h1>{{job.source.name}}/{{job.source.version}} {{job.name}}</h1>
+ <div class='desc_line'>
+ <div class='desc_key'>Source</div>
+ <div class='desc_value'><a href='{{info.source_link}}'>{{job.source.name}}/{{job.source.version}}</a></div>
+ </div>
+ {% if job.binary %}
+ <div class='desc_line'>
+ <div class='desc_key'>Binary</div>
+ <div class='desc_value'><a href='{{info.binary_link}}'>{{job.binary.name}}/{{job.binary.version}}</a></div>
+ </div>
+ {% endif %}
+ <div class='desc_line'>
+ <div class='desc_key'>Job</div>
+ <div class='desc_value'>{{job.name}}</div>
+ </div>
+ <div class='desc_line'>
+ <div class='desc_key'>Group</div>
+ <div class='desc_value'><a href='{{info.group_link}}'>{{job.group.name}}</a></div>
+ <div>
+ <div class='desc_line'>
+ <div class='desc_key'>Suite</div>
+ <div class='desc_value'>{{job.suite.name}}</div>
+ </div>
+ <div class='desc_line'>
+ <div class='desc_key'>Component</div>
+ <div class='desc_value'>{{job.component.name}}</div>
+ </div>
+ <div class='desc_line'>
+ <div class='desc_key'>Check</div>
+ <div class='desc_value'>{{job.check.name}}</div>
+ </div>
+ <div class='desc_line'>
+ <div class='desc_key'>Architecture</div>
+ <div class='desc_value'>{{job.arch.name}}</div>
+ </div>
+ <div class='desc_line'>
+ <div class='desc_key'>Arch affinity</div>
+ <div class='desc_value'>{{job.affinity.name}}</div>
+ </div>
+ {% if job.builder %}
+ <div class='desc_line'>
+ <div class='desc_key'>Builder</div>
+ <div class='desc_value'><a href='{{info.builder_link}}'>{{job.builder.name}}</a></div>
+ </div>
+ <div class='desc_line'>
+ <div class='desc_key'>Build time</div>
+ <div class='desc_value'>{{info.job_runtime}}</div>
+ </div>
+ {% endif %}
+ <div class='desc_line'>
+ <div class='desc_key'>Status</div>
+ <div class='desc_value'>
+ {% if job.finished_at %}
+ {% if job.check.build %}
+ {# Builds #}
+ {% if job.failed %}Failed{% else %}Uploaded{% endif %}
+ {% else %}
+ {# Analyzers #}
+ {% if job.failed %}✗ Errors found{% else %}✓ No errors found{% endif %}
+ {% endif %}
+ {% else %}
+ Needs-Build
+ {% endif %}
+ </div>
+ </div>
+ </div>
+
+ {% if job.finished_at %}
+ <div class='block'>
+ <h3>Downloads</h3>
+ <div class='desc_line'>
+ <div class='desc_key'>Uploaded dud</div>
+ <div class='desc_value'><a href='{{info.dud_link}}'>{{info.dud_name}}</a></div>
+ </div>
+ <div class='desc_line'>
+ <div class='desc_key'>Job Log</div>
+ <div class='desc_value'><a href='{{info.log_link}}'>{{info.log_name}}</a></div>
+ </div>
+ <div class='desc_line'>
+ <div class='desc_key'>Firehose Report</div>
+ <div class='desc_value'><a href='{{info.firehose_link}}'>{{info.firehose_name}}</a></div>
+ </div>
+ {% if info.files %}
+ <div class='desc_line'>
+ <div class='desc_key'>Additional Files</div>
+ <div class='desc_value'>
+ {% for file in info.files %}
+ <a href='{{job.files_url}}/{{file}}'>{{file}}</a><br />
+ {% endfor %}
+ </div>
+ </div>
+ {% endif %}
+ </div>
+ {% endif %}
+
+{% endblock %}
diff --git a/templates/job_list_fragment.html b/templates/job_list_fragment.html
index 865c91d..07c3319 100644
--- a/templates/job_list_fragment.html
+++ b/templates/job_list_fragment.html
@@ -1,28 +1,58 @@
- <table class = 'zebra'>
+ <table>
<tr>
- <th>Source Package</th>
- <th>Type</th>
- <th>Arch</th>
+ <th>Source</th>
+ <th>Job</th>
+ <th>Group</th>
<th>Suite</th>
- <th>Assigned</th>
<th>Builder</th>
+ <th>Status</th>
</tr>
-{% for jobinfo in active_jobs_info %}
- <tr>
+
+{% for info in jobs_info %}
+ <tr class='job {{info.status}}'>
+ <td>
+ {% if info.source_link %}
+ <a href='{{info.source_link}}'>{{info.job.source.name}}/{{info.job.source.version}}</a>
+ {% else %}
+ {{info.job.source.name}}/{{info.job.source.version}}
+ {% endif %}
+ </td>
+ <td>
+ <a href = '{{info.job_link}}' >{{info.job.name}}</a>
+ </td>
<td>
- <a href = '{{jobinfo.package_link}}' >{{jobinfo.job.package.name}}</a><br />{{jobinfo.job.package.version}}
+ {% if info.group_link %}
+ <a href='{{info.group_link}}'>{{info.job.group.name}}</a>
+ {% else %}
+ {{info.job.group.name}}
+ {% endif %}
+ </td>
+ <td>
+ {{info.job.suite.name}}
+ </td>
+ <td>
+ {% if info.builder_link %}
+ <a href = '{{info.builder_link}}' >{{info.job.builder.name}}</a>
+ {% elif info.job.builder %}
+ {{info.job.builder.name}}
+ {% else %}
+ Not-Assigned
+ {% endif %}
</td>
- <td>{{jobinfo.job.type}}{% if jobinfo.job.subtype %}/{{jobinfo.job.subtype}}{% endif %}</td>
- <td>{{jobinfo.job.arch}}</td>
- <td>{{jobinfo.job.suite}}</td>
- <td>{{jobinfo.job.assigned_at|ago}}</td>
<td>
- {% if jobinfo.job.machine %}
- <a href = '{{jobinfo.machine_link}}' >{{jobinfo.job.machine.name}}</a>
+ {% if info.job.finished_at %}
+ {% if info.job.check.build %}
+ {# Builds #}
+ {% if info.job.failed %}Failed{% else %}Uploaded{% endif %}
+ {% else %}
+ {# Analyzers #}
+ {% if info.job.failed %}✗ Errors found{% else %}✓ No errors found{% endif %}
+ {% endif %}
{% else %}
- <em>not assigned</em>
+ Needs-Build
{% endif %}
</td>
</tr>
{% endfor %}
+
</table>
diff --git a/templates/jobs.html b/templates/jobs.html
new file mode 100644
index 0000000..5835593
--- /dev/null
+++ b/templates/jobs.html
@@ -0,0 +1,14 @@
+{% extends "base.html" %}
+
+{% block title %}Job List{% endblock %}
+
+{% block content %}
+ <h1>Job list</h1>
+ {% if info.desc %}{{info.desc}}{% endif %}
+
+ {% if info.prev_link %}<a class='left' href='{{info.prev_link}}'>previous page</a>{% endif %}
+ {% if info.next_link %}<a class='right' href='{{info.next_link}}'>next page</a>{% endif %}
+ <div class = 'clear' ></div>
+ {% include "job_list_fragment.html" %}
+
+{% endblock %}
diff --git a/templates/machine.html b/templates/machine.html
deleted file mode 100644
index 09310d5..0000000
--- a/templates/machine.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "base.html" %}
-
-{% block title %}Machine{% endblock %}
-
-{% block content %}
-<h1>{{machine.name}}</h1>
-
-The full GPG
-fingerprint of this buildd is <code>{{machine.gpg_fingerprint}}</code>. This machine
-last hit us authenticated {{machine.last_ping|ago}}.
-{% endblock %}
diff --git a/templates/machine_list_fragment.html b/templates/machine_list_fragment.html
deleted file mode 100644
index b7f7d6a..0000000
--- a/templates/machine_list_fragment.html
+++ /dev/null
@@ -1,21 +0,0 @@
- <table class = 'zebra'>
- <tr>
- <th>Name</th>
- <th>Last ping</th>
- <th>Jobs</th>
- </tr>
-{% for machine in machines %}
- <tr>
- <td><a href = '/machine/{{machine.name}}' >{{machine.name}}</a></td>
- <td>{{machine.last_ping|ago}}</td>
- <td>
- {% for job in machine.jobs%}
- {% if not job.finished_at %}
- <a href = '/report/{{job.id}}' >{{job.type}}</a>
- {% endif %}
- {% endfor %}
- </td>
- </tr>
-{% endfor %}
- </table>
-
diff --git a/templates/macros.inc.html b/templates/macros.inc.html
deleted file mode 100644
index d70c1f7..0000000
--- a/templates/macros.inc.html
+++ /dev/null
@@ -1,10 +0,0 @@
-
-{% macro render_packages_prefixes(prefixes) %}
- {%- for prefix in prefixes %}
-{# <a href="{{ url_for('prefix', prefix_id=prefix) }}">{{ prefix }}</a>
-#}
- <a href="/prefix/{{ prefix }}">{{ prefix }}</a>
-
- {%- endfor %}
-{% endmacro %}
-
diff --git a/templates/prefix.html b/templates/prefix.html
deleted file mode 100644
index 8d46173..0000000
--- a/templates/prefix.html
+++ /dev/null
@@ -1,8 +0,0 @@
-{% extends "base.html" %}
-
-{% block title %}Package List{% endblock %}
-
-{% block content %}
- <h1>Package list: '{{prefix}}'</h1>
- {% include "prefix_list.html" %}
-{% endblock %}
diff --git a/templates/prefix_list.html b/templates/prefix_list.html
deleted file mode 100644
index 42ae93c..0000000
--- a/templates/prefix_list.html
+++ /dev/null
@@ -1,37 +0,0 @@
- <table class = 'zebra'>
- <tr>
- <th>What</th>
- <th>Latest version</th>
-{# <th>Uploader</th>
- <th>Status</th>#}
- </tr>
-{% for info in sources %}
- <tr>
- <td>
- <a href = '{{info.source_link}}' >
-{{info.source.name}}
-</td>
-<td>
-{{info.source.version}}
-</td>
-
-{# {{info.source.name}}/{{info.source.version}}{% if info.source.run > 1 %} - run {{info.source.run}}{% endif %}
-
- </a>
- </td>
- <td>
- {% if info.source.group %}
- <a href = '{{info.group_link}}' >
- {{info.source.group.name}}
- </a>
- {% endif %}
- </td>
- <td>
- <a href = '{{info.user_link}}' >
- {{info.source.user.name}}
- </a>
- </td>
- </tr>
-#}
-{% endfor %}
- </table>
diff --git a/templates/report.html b/templates/report.html
deleted file mode 100644
index 2953d69..0000000
--- a/templates/report.html
+++ /dev/null
@@ -1,35 +0,0 @@
-{% extends "base.html" %}
-
-{% block title %}Report for job id={{job_info.job.id}}{% endblock %}
-
-{% block content %}
-{% if job_info.job.package.type == 'binary' %}
-{% include 'report_desc_binary.html' %}
-{% else %}
-{% include 'report_desc_source.html' %}
-{% endif %}
-
-{% if job_info.job.failed %}
- <div class='block'>
- <h2>This job failed, check the reports and file/fix potential bugs.</h2>
- </div>
- {% if scanbuild_link %}
- <div class='block'>
- <h3>Scan-build output</h3>
- <div class='desc_line'>
- <div class='desc_key'>HTML formatted</div>
- <div class='desc_value'><a href='{{scanbuild_link}}'>see report</a></div>
- </div>
- </div>
- {% endif %}
-{% else %}
- <div class='block'>
- <h2>This job succeeded. No results have been found.</h2>
- </div>
-{% endif %}
-
-<h1>Full Log</h1>
-<a name="full_log" />
-<pre>
-{% for line in log %}{{line}}{% endfor %}</pre>
-{% endblock %}
diff --git a/templates/report_desc_binary.html b/templates/report_desc_binary.html
deleted file mode 100644
index f80e7d3..0000000
--- a/templates/report_desc_binary.html
+++ /dev/null
@@ -1,44 +0,0 @@
- <div class='block'>
- <h3>Job info</h3>
- <div class='desc_line'>
- <div class='desc_key'>type</div>
- <div class='desc_value'>{{job_info.job.type}}</div>
- </div>
- <div class='desc_line'>
- <div class='desc_key'>Builder</div>
- <div class='desc_value'><a href='{{job_info.machine_link}}'>{{job_info.job.machine.name}}</a></div>
- </div>
- {% if job_info.job.type == 'build' %}
- <div class='desc_line'>
- <div class='desc_key'>Compiler setup</div>
- <div class='desc_value'>{{job_info.job.subtype}}</div>
- </div>
- {% endif %}
- <div class='desc_line'>
- <div class='desc_key'>Binary package</div>
- <div class='desc_value'>{{job_info.job.package.name}} {{job_info.job.package.version}}</div>
- </div>
- <div class='desc_line'>
- <div class='desc_key'>Source package</div>
- <div class='desc_value'><a href="{{job_info.source_link}}">{{job_info.job.package.source.name}}</a></div>
- </div>
- <div class='desc_line'>
- <div class='desc_key'>Build time </div>
- <div class='desc_value'>{{job_info.job_runtime}}</div>
- </div>
- </div>
- <div class='block'>
- <h3>Downloads</h3>
- <div class='desc_line'>
- <div class='desc_key'>Binary .deb</div>
- <div class='desc_value'><a href='{{job_info.deb_link}}'>{{job_info.job.package.deb}}</a></div>
- </div>
- <div class='desc_line'>
- <div class='desc_key'>Job log</div>
- <div class='desc_value'><a href='{{log_link}}'>Text format</a></div>
- </div>
- <div class='desc_line'>
- <div class='desc_key'>Firehose report</div>
- <div class='desc_value'><a href='{{firehose_link}}'>XML format</a></div>
- </div>
- </div>
diff --git a/templates/report_desc_source.html b/templates/report_desc_source.html
deleted file mode 100644
index 248ed81..0000000
--- a/templates/report_desc_source.html
+++ /dev/null
@@ -1,36 +0,0 @@
- <div class='block'>
- <h3>Job info</h3>
- <div class='desc_line'>
- <div class='desc_key'>type</div>
- <div class='desc_value'>{{job_info.job.type}}</div>
- </div>
- {% if job_info.job.subtype %}
- <div class='desc_line'>
- <div class='desc_key'>subtype</div>
- <div class='desc_value'>{{job_info.job.subtype}}</div>
- </div>
- {% endif %}
- <div class='desc_line'>
- <div class='desc_key'>builder</div>
- <div class='desc_value'><a href='{{job_info.machine_link}}'>{{job_info.job.machine.name}}</a></div>
- </div>
- <div class='desc_line'>
- <div class='desc_key'>source package</div>
- <div class='desc_value'><a href='{{job_info.package_link}}'>{{job_info.job.package.name}} {{job_info.job.package.version}}</a></div>
- </div>
- <div class='desc_line'>
- <div class='desc_key'>Build time</div>
- <div class='desc_value'>{{job_info.job_runtime}}</div>
- </div>
- </div>
- <div class='block'>
- <h3>Downloads</h3>
- <div class='desc_line'>
- <div class='desc_key'>job log</div>
- <div class='desc_value'><a href='{{log_link}}'>Text format</a></div>
- </div>
- <div class='desc_line'>
- <div class='desc_key'>firehose report</div>
- <div class='desc_value'><a href='{{firehose_link}}'>XML format</a></div>
- </div>
- </div>
diff --git a/templates/report_list_binary_fragment.html b/templates/report_list_binary_fragment.html
deleted file mode 100644
index 0f2a531..0000000
--- a/templates/report_list_binary_fragment.html
+++ /dev/null
@@ -1,37 +0,0 @@
- <table>
- <tr>
- <th>Type</th>
- <th>Name</th>
- <th>Status</th>
- <th>Machine</th>
- <th>Results</th>
- </tr>
-{% for jobinfo in jobinfolist %}
- <tr class='job {% if jobinfo.job.is_finished() %}{% if jobinfo.job.failed %}failed{% else %}success{% endif %}{% endif %}'>
- <td>
- {% if jobinfo.job.is_finished() %}
- <a href = '{{jobinfo.job_link}}' >{{jobinfo.job.type}}</a> <em>({{jobinfo.job.arch}})</em>
- {% else %}
- {{jobinfo.job.type}} <em>({{jobinfo.job.arch}})</em>
- {% endif %}
- </td>
- <td>{{jobinfo.job.package.name}}</td>
- <td>{{jobinfo.status}}</td>
- <td>
- {% if jobinfo.job.machine %}
- <a href = '{{jobinfo.job_machine_link}}' >{{jobinfo.job.machine.name}}</a>
- {% else %}
- not assigned yet
- {% endif %}
- </td>
- <td>{% if jobinfo.job.is_finished() %}{% if jobinfo.job.failed %}✗ Errors found{% else %}✓ Nothing found{% endif %}{% endif %}</td>
- </tr>
-{% endfor %}
-{% if jobinfolist|length == 0 %}
- <tr class='emptymessage'>
- <td colspan='4'>
- {{emptymessage}}
- </td>
- </tr>
-{% endif %}
- </table>
diff --git a/templates/report_list_fragment.html b/templates/report_list_fragment.html
deleted file mode 100644
index 7cb33d9..0000000
--- a/templates/report_list_fragment.html
+++ /dev/null
@@ -1,52 +0,0 @@
- <table>
- <tr>
- <th>Type</th>
- <th>Version</th>
- <th>Machine</th>
- <th>Results</th>
- </tr>
-{% set typebuild = '' %}
-
-{% for jobinfo in jobinfolist %}
-{# Add an empty line between the normal build + static analyzers #}
-{% if typebuildprev == "build" and typebuildprev != jobinfo.job.type %}<tr><td colspan="4"> </td></tr>{% endif %}
-
- <tr class='job {% if jobinfo.job.is_finished() %}{% if jobinfo.job.failed %}failed{% else %}success{% endif %}{% endif %}'>
- <td>
- {% if jobinfo.job.is_finished() %}
- <a href = '{{jobinfo.job_link}}' >{{jobinfo.job.type}}{% if jobinfo.job.subtype %}/{{jobinfo.job.subtype}}{% endif %}</a> <em>({{jobinfo.job.arch}})</em>
- {% else %}
- {{jobinfo.job.type}}{% if jobinfo.job.subtype %}/{{jobinfo.job.subtype}}{% endif %} <em>({{jobinfo.job.arch}})</em>
- {% endif %}
- </td>
- <td>{{package.version}}</td>
- <td>
- {% if jobinfo.job.machine %}
- <a href = '{{jobinfo.job_machine_link}}' >{{jobinfo.job.machine.name}}</a>
- {% else %}
- not assigned yet
- {% endif %}
- </td>
- <td>{% if jobinfo.job.is_finished() %}
- {% if jobinfo.job.type == "build" %} {# Build of the package package #}
- {% if jobinfo.job.failed %}Failed{% else %}Uploaded{% endif %}
- {% else %} {# Analyzers #}
- {% if jobinfo.job.failed %}<a href='{{jobinfo.job_report_link}}'>✗ Errors found</a>{% else %}✓ Nothing found{% endif %}
- {% endif %}
- {% else %}
- Needs-Build
- {% endif %}
- </td>
-
-{% set typebuildprev = jobinfo.job.type %}
-
- </tr>
-{% endfor %}
-{% if jobinfolist|length == 0 %}
- <tr class='emptymessage'>
- <td colspan='4'>
- {{emptymessage}}
- </td>
- </tr>
-{% endif %}
- </table>
diff --git a/templates/repository.html b/templates/repository.html
deleted file mode 100644
index bb42f29..0000000
--- a/templates/repository.html
+++ /dev/null
@@ -1,21 +0,0 @@
-{% extends "base.html" %}
-
-{% block title %}Repository{% endblock %}
-
-{% block content %}
-<h1>{{worker.name}}</h1>
-
-{{worker.name}}'s GPG key is <code>{{worker.gpg_fingerprint}}</code>.
-
-<h2>Repositories of packages</h2>
-Choose to add one of the following mirrors to <strong>/etc/apt/sources.list.d/debile.list</strong>
-<pre>
-{{apt_binary_list}}
-</pre>
-
-<h2>Source repository</h2>
-Add the following mirror(s) to <strong>/etc/apt/sources.list.d/debile.list</strong>
-<pre>
-{{apt_source_list}}
-</pre>
-{% endblock %}
diff --git a/templates/search.html b/templates/search.html
index b9fda0e..db6af55 100644
--- a/templates/search.html
+++ b/templates/search.html
@@ -8,15 +8,15 @@
<script type="text/javascript">
$(function() {
- $( "#package" ).autocomplete({
+ $( "#source" ).autocomplete({
source: function( request, response ) {
- $.getJSON($SCRIPT_ROOT + "/_search_package", {
+ $.getJSON($SCRIPT_ROOT + "/_search_source", {
search: request
}, response);
},
select: function(event, ui) {
- $("#package").val(ui.item.label);
- $("#searchPackageForm").submit(); }
+ $("#source").val(ui.item.label);
+ $("#searchSourceForm").submit(); }
})
});
@@ -41,9 +41,9 @@
}
</style>
-<table><tr><td>By package</td><td>
-<form id="searchPackageForm" action="/source/search/" method="POST">
- <div class="ui-widget">{{form.package(size=20)}}
+<table><tr><td>By source</td><td>
+<form id="searchSourceForm" action="/source/search/" method="POST">
+ <div class="ui-widget">{{form.source(size=20)}}
<input type="submit" value="Search" /></div>
</form>
</td></tr>
diff --git a/templates/source-not-found.html b/templates/source-not-found.html
index 4e83188..0c78c7c 100644
--- a/templates/source-not-found.html
+++ b/templates/source-not-found.html
@@ -4,9 +4,7 @@
{% block content %}
-Package <i>{{ package_name }}</i> {% if version %} {{ version }} {% endif %} not found
-{% if version %}<br />
-Try the <a href="/source/fred/{{ package_name }}/latest/1">latest release</a>
-{% endif %}
+Package <i>{{package_name}}/{{version_or_suite}}</i> not found in group <i>{{group_name}}</i><br />
+You can try to search for packages named <a href="/source/{{package_name}}">{{package_name}}</a> instead.<br />
{% endblock %}
diff --git a/templates/source.html b/templates/source.html
index f452a51..4d82ab3 100644
--- a/templates/source.html
+++ b/templates/source.html
@@ -1,10 +1,10 @@
{% extends "base.html" %}
-{% block title %}Package {{package.name}}/{{package.version}}{% endblock %}
+{% block title %}{{source.name}}/{{source.version}}{% endblock %}
{% block content %}
-{% with total, unfinished = package_job_status %}
+{% with total, unfinished = info.job_status %}
<div class = 'box' >
<div class = 'unfinished' >
{{unfinished}}<span class = 'total' >/{{total}}</span>
@@ -13,61 +13,56 @@
</div>
{% endwith %}
-
<div class='block'>
- <h3>Package info</h3>
+ <h1>{{source.name}}/{{source.version}}</h1>
<div class='desc_line'>
<div class='desc_key'>Name</div>
- <div class='desc_value'>{{package.name}}</div>
+ <div class='desc_value'>{{source.name}}</div>
</div>
<div class='desc_line'>
<div class='desc_key'>Version</div>
- <div class='desc_value'>{{package.version}}</div>
+ <div class='desc_value'>{{source.version}}</div>
+ </div>
+ <div class='desc_line'>
+ <div class='desc_key'>Group</div>
+ <div class='desc_value'><a href='{{info.group_link}}'>{{source.group.name}}</a></div>
</div>
<div class='desc_line'>
- <div class='desc_key'>Maintainer</div>
- <div class='desc_value'>{{package.maintainer}}</div>
+ <div class='desc_key'>Suite</div>
+ <div class='desc_value'>{{source.suite.name}}</div>
</div>
<div class='desc_line'>
- <div class='desc_key'>Built by</div>
- <div class='desc_value'><a href='{{desc.user_link}}'>{{package.user.name}}</a></div>
+ <div class='desc_key'>Component</div>
+ <div class='desc_value'>{{source.component.name}}</div>
</div>
<div class='desc_line'>
- <div class='desc_key'>Available on</div>
- <div class='desc_value'><a href='{{desc.user_repository_link}}'>Repository</a></div>
+ <div class='desc_key'>Uploader</div>
+ <div class='desc_value'><a href='{{info.uploader_link}}'>{{source.uploader.name}}</a></div>
</div>
</div>
- {% if multiple_runs %}
<div class='block'>
- <h3>debile runs</h3>
- {% if latest_run == package.run %}
- This is the latest run of debile available for this package, but you can access previous runs:
- {% else %}
- This package version has been processed multiple times, see other runs:
- {% endif %}
- <div class='package_runs_menu'>
- {% for run, link in runs_info %}
- <div class='package_runs_menu_element {% if desc.run == run %}current_run{% endif %}'>
- <a href='{{link}}'>{{run}}{% if loop.last %} (latest){% endif %}</a>
+ <h3>(Co-)Maintainers</h3>
+ <div class='package_maintainers_menu'>
+ {% for maintainer in source.maintainers %}
+ <div class='package_maintainers_menu_element'>
+ {{maintainer.name}} <{{maintainer.email}}>
</div>
- {% if not loop.last %} | {% endif %}
{% endfor %}
</div>
</div>
- {% endif %}
- {% if multiple_versions %}
+ {% if versions_info %}
<div class='block'>
- <h3>Versions</h3>
+ <h3>Other Versions</h3>
<div class='package_versions_menu'>
{% for version, link in versions_info %}
<div class='package_versions_menu_element'>
- {% if version == package.version %}
- {{version}}{% if loop.last %} (latest){% endif %}
- {% else %}
- <a href='{{link}}'>{{version}}{% if loop.last %} (latest){% endif %}</a>
- {% endif %}
+ {% if version == source.version %}
+ {{version}}
+ {% else %}
+ <a href='{{link}}'>{{version}}</a>
+ {% endif %}
</div>
{% endfor %}
</div>
@@ -75,23 +70,8 @@
{% endif %}
<div class='block'>
- <h3>source jobs</h3>
- launched on the source package provided
-{% with jobinfolist = source_jobs_info %}
-{% with emptymessage = 'Ahem, this is weird, there should be jobs here, call us...' %}
- {% include "report_list_fragment.html" %}
-{% endwith %}
-{% endwith %}
- </div>
-
- <div class='block'>
- <h3>binary jobs</h3>
-launched on the binaries uploaded after the build of the source package
-{% with jobinfolist = binaries_jobs_info %}
-{% with emptymessage = 'No binary jobs yet, check the build jobs above.' %}
- {% include "report_list_binary_fragment.html" %}
-{% endwith %}
-{% endwith %}
+ <h3>Jobs</h3>
+ {% include "job_list_fragment.html" %}
</div>
{% endblock %}
diff --git a/templates/source_list.html b/templates/source_list.html
deleted file mode 100644
index 51c5452..0000000
--- a/templates/source_list.html
+++ /dev/null
@@ -1,8 +0,0 @@
-{% extends "base.html" %}
-
-{% block title %}Package List{% endblock %}
-
-{% block content %}
- <h1>{{count}} most recently uploaded source packages</h1>
- {% include "source_list_fragment.html" %}
-{% endblock %}
diff --git a/templates/source_list_fragment.html b/templates/source_list_fragment.html
index 9be8ca9..0d9fdb4 100644
--- a/templates/source_list_fragment.html
+++ b/templates/source_list_fragment.html
@@ -1,50 +1,52 @@
<table class = 'zebra'>
<tr>
- <th>What</th>
+ <th>Source</th>
<th>Group</th>
+ <th>Suite</th>
<th>Uploader</th>
<th>Status</th>
</tr>
+
{% for info in sources_info %}
<tr>
<td>
- <a href = '{{info.source_link}}' >
- {{info.source.name}}/{{info.source.version}}{% if info.source.run > 1 %} - run {{info.source.run}}{% endif %}
- </a>
+ <a href='{{info.source_link}}'>{{info.source.name}}/{{info.source.version}}</a>
</td>
<td>
- {% if info.source.group %}
- <a href = '{{info.group_link}}' >
+ {% if info.group_link %}
+ <a href='{{info.group_link}}'>{{info.source.group.name}}</a>
+ {% else %}
{{info.source.group.name}}
- </a>
{% endif %}
</td>
<td>
- <a href = '{{info.user_link}}' >
- {{info.source.user.name}}
- </a>
+ {{info.source.suite.name}}
</td>
<td>
- {% for jerb in info.source.jobs %}
- {% if jerb.is_pending() %}
- {% if jerb.builder %}
- ⧖
- {% else %}
- ⌚
- {% endif %}
+ {% if info.upploader_link %}
+ <a href = '{{info.uploader_link}}' >{{info.source.uploader.name}}</a>
{% else %}
- {% if jerb.failed %}
- {% if jerb.is_critical() %}
- ☹
- {% else %}
+ {{info.source.uploader.name}}
+ {% endif %}
+ </td>
+ <td>
+ {% for job in info.source.jobs %}
+ {% if job.finished_at %}
+ {% if job.failed %}
✗
+ {% else %}
+ ✓
{% endif %}
{% else %}
- ✓
+ {% if job.assigned_at %}
+ ⧖
+ {% else %}
+ ⌚
+ {% endif %}
{% endif %}
- {% endif %}
- {% endfor %}
+ {% endfor %}
</td>
</tr>
{% endfor %}
+
</table>
diff --git a/templates/sources.html b/templates/sources.html
new file mode 100644
index 0000000..2e654f2
--- /dev/null
+++ b/templates/sources.html
@@ -0,0 +1,14 @@
+{% extends "base.html" %}
+
+{% block title %}Package List{% endblock %}
+
+{% block content %}
+ <h1>Package list</h1>
+ {% if info.desc %}{{info.desc}}{% endif %}
+
+ {% if info.prev_link %}<a class='left' href='{{info.prev_link}}'>previous page</a>{% endif %}
+ {% if info.next_link %}<a class='right' href='{{info.next_link}}'>next page</a>{% endif %}
+ <div class = 'clear' ></div>
+ {% include "source_list_fragment.html" %}
+
+{% endblock %}
diff --git a/templates/user.html b/templates/user.html
new file mode 100644
index 0000000..623c6f7
--- /dev/null
+++ b/templates/user.html
@@ -0,0 +1,42 @@
+{% extends "base.html" %}
+
+{% block title %}{{user.name}}{% endblock %}
+
+{% block content %}
+ <h1>{{user.name}}</h1>
+ <div class='block'>
+ <div class='desc_line'>
+ <div class='desc_key'>Name</div>
+ <div class='desc_value'>{{user.name}}</div>
+ </div>
+ <div class='desc_line'>
+ <div class='desc_key'>Email</div>
+ <div class='desc_value'><a href='mailto:{{user.email}}'>{{user.email}}</a></div>
+ </div>
+ <div class='desc_line'>
+ <div class='desc_key'>PGP Fingerprint:</div>
+ <div class='desc_value'>{{user.pgp}}</div>
+ </div>
+ <div class='desc_line'>
+ <div class='desc_key'>SSL Fingerprint:</div>
+ <div class='desc_value'>{{user.ssl}}</div>
+ </div>
+ </div>
+
+ {% if groups_info %}
+ <h3>Groups Maintained by {{user.name}}</h3>
+ {% include "groups_list_fragment.html" %}
+ {%endif}
+
+ {% if builders_info %}
+ <h3>Builders Maintained by {{user.name}}</h3>
+ {% include "builder_list_fragment.html" %}
+ {%endif}
+
+ <h3>Sources Uploaded by {{user.name}}</h3>
+ {% if info.prev_link %}<a class='left' href='{{info.prev_link}}'>previous page</a>{% endif %}
+ {% if info.next_link %}<a class='right' href='{{info.next_link}}'>next page</a>{% endif %}
+ <div class = 'clear' ></div>
+ {% include "source_list_fragment.html" %}
+
+{% endblock %}
diff --git a/templates/worker.html b/templates/worker.html
deleted file mode 100644
index af7f20d..0000000
--- a/templates/worker.html
+++ /dev/null
@@ -1,19 +0,0 @@
-{% extends "base.html" %}
-
-{% block title %}Worker{% endblock %}
-
-{% block content %}
-<h1>{{worker.name}}</h1>
-
-{{worker.name}}'s GPG key is <code>{{worker.gpg_fingerprint}}</code>.
-
-<h2>Upload your source package to debile</h2>
-Follow our one-minute-very-easy-even-for-noobs setup guide.
-<ul>
- <li>Install dput-ng</li>
- <li>Copy the following in your <strong>~/.dput.d/profiles/debile.json</strong></li>
-</ul>
-<pre>
-{{dput_upload_profile}}
-</pre>
-{% endblock %}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-debile/debile-web.git
More information about the Pkg-debile-commits
mailing list