mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-04-24 07:17:17 +00:00
web templates improvements
* enable jinja autoescape by default for jinja raw generator * allow to search by multiple strings (OR) * replace test templates by symlink
This commit is contained in:
parent
47c4e5bb42
commit
78636c2035
@ -1,7 +1,7 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>{{ repository|e }}</title>
|
<title>{{ repository }}</title>
|
||||||
|
|
||||||
{% include "style.jinja2" %}
|
{% include "style.jinja2" %}
|
||||||
|
|
||||||
@ -12,9 +12,9 @@
|
|||||||
<body>
|
<body>
|
||||||
<div class="root">
|
<div class="root">
|
||||||
<h1>ahriman
|
<h1>ahriman
|
||||||
<img src="https://img.shields.io/badge/version-{{ version|e }}-informational" alt="{{ version|e }}">
|
<img src="https://img.shields.io/badge/version-{{ version }}-informational" alt="{{ version }}">
|
||||||
<img src="https://img.shields.io/badge/architecture-{{ architecture|e }}-informational" alt="{{ architecture|e }}">
|
<img src="https://img.shields.io/badge/architecture-{{ architecture }}-informational" alt="{{ architecture }}">
|
||||||
<img src="https://img.shields.io/badge/service%20status-{{ service.status|e }}-{{ service.status_color|e }}" alt="{{ service.status|e }}" title="{{ service.timestamp|e }}">
|
<img src="https://img.shields.io/badge/service%20status-{{ service.status }}-{{ service.status_color }}" alt="{{ service.status }}" title="{{ service.timestamp }}">
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
{% include "search-line.jinja2" %}
|
{% include "search-line.jinja2" %}
|
||||||
@ -31,11 +31,11 @@
|
|||||||
|
|
||||||
{% for package in packages %}
|
{% for package in packages %}
|
||||||
<tr class="package">
|
<tr class="package">
|
||||||
<td class="include-search"><a href="{{ package.web_url|e }}" title="{{ package.base|e }}">{{ package.base|e }}</a></td>
|
<td class="include-search"><a href="{{ package.web_url }}" title="{{ package.base }}">{{ package.base }}</a></td>
|
||||||
<td class="include-search">{{ package.packages|join("<br>"|safe) }}</td>
|
<td class="include-search">{{ package.packages|join("<br>"|safe) }}</td>
|
||||||
<td>{{ package.version|e }}</td>
|
<td>{{ package.version }}</td>
|
||||||
<td>{{ package.timestamp|e }}</td>
|
<td>{{ package.timestamp }}</td>
|
||||||
<td class="status package-{{ package.status|e }}">{{ package.status|e }}</td>
|
<td class="status package-{{ package.status }}">{{ package.status }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>{{ repository|e }}</title>
|
<title>{{ repository }}</title>
|
||||||
|
|
||||||
{% include "style.jinja2" %}
|
{% include "style.jinja2" %}
|
||||||
|
|
||||||
@ -18,13 +18,13 @@
|
|||||||
|
|
||||||
<section class="element">
|
<section class="element">
|
||||||
{% if pgp_key is not none %}
|
{% if pgp_key is not none %}
|
||||||
<p>This repository is signed with <a href="http://keys.gnupg.net/pks/lookup?search=0x{{ pgp_key|e }}&fingerprint=on&op=index" title="key search">{{ pgp_key|e }}</a> by default.</p>
|
<p>This repository is signed with <a href="http://keys.gnupg.net/pks/lookup?search=0x{{ pgp_key }}&fingerprint=on&op=index" title="key search">{{ pgp_key }}</a> by default.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<code>
|
<code>
|
||||||
$ cat /etc/pacman.conf<br>
|
$ cat /etc/pacman.conf<br>
|
||||||
[{{ repository|e }}]<br>
|
[{{ repository }}]<br>
|
||||||
Server = {{ link_path|e }}<br>
|
Server = {{ link_path }}<br>
|
||||||
SigLevel = Database{% if has_repo_signed %}Required{% else %}Never{% endif %} Package{% if has_package_signed %}Required{% else %}Never{% endif %} TrustedOnly
|
SigLevel = Database{% if has_repo_signed %}Required{% else %}Never{% endif %} Package{% if has_package_signed %}Required{% else %}Never{% endif %} TrustedOnly
|
||||||
</code>
|
</code>
|
||||||
</section>
|
</section>
|
||||||
@ -44,11 +44,11 @@
|
|||||||
|
|
||||||
{% for package in packages %}
|
{% for package in packages %}
|
||||||
<tr class="package">
|
<tr class="package">
|
||||||
<td class="include-search"><a href="{{ link_path|e }}/{{ package.filename|e }}" title="{{ package.name|e }}">{{ package.name|e }}</a></td>
|
<td class="include-search"><a href="{{ link_path }}/{{ package.filename }}" title="{{ package.name }}">{{ package.name }}</a></td>
|
||||||
<td>{{ package.version|e }}</td>
|
<td>{{ package.version }}</td>
|
||||||
<td>{{ package.archive_size|e }}</td>
|
<td>{{ package.archive_size }}</td>
|
||||||
<td>{{ package.installed_size|e }}</td>
|
<td>{{ package.installed_size }}</td>
|
||||||
<td>{{ package.build_date|e }}</td>
|
<td>{{ package.build_date }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
@ -58,7 +58,7 @@
|
|||||||
<footer>
|
<footer>
|
||||||
<ul class="navigation">
|
<ul class="navigation">
|
||||||
{% if homepage is not none %}
|
{% if homepage is not none %}
|
||||||
<li><a href="{{ homepage|e }}" title="homepage">Homepage</a></li>
|
<li><a href="{{ homepage }}" title="homepage">Homepage</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
</footer>
|
</footer>
|
||||||
|
@ -5,20 +5,21 @@
|
|||||||
const tables = document.getElementsByClassName("search-table");
|
const tables = document.getElementsByClassName("search-table");
|
||||||
|
|
||||||
for (let i = 0; i < tables.length; i++) {
|
for (let i = 0; i < tables.length; i++) {
|
||||||
const tr = tables[i].getElementsByTagName("tr");
|
const trs = tables[i].getElementsByTagName("tr");
|
||||||
// from 1 coz of header
|
// from 1 coz of header
|
||||||
for (let i = 1; i < tr.length; i++) {
|
for (let i = 1; i < trs.length; i++) {
|
||||||
let td = tr[i].getElementsByClassName("include-search");
|
let tr = trs[i].getElementsByClassName("include-search");
|
||||||
let display = "none";
|
let display = "none";
|
||||||
for (let j = 0; j < td.length; j++) {
|
for (let j = 0; j < tr.length; j++) {
|
||||||
if (td[j].tagName.toLowerCase() === "td") {
|
if (tr[j].tagName.toLowerCase() === "td") {
|
||||||
if (td[j].innerHTML.toLowerCase().indexOf(filter) > -1) {
|
let contains = (element) => tr[j].innerHTML.toLowerCase().indexOf(element) > -1
|
||||||
|
if (filter.some(contains)) {
|
||||||
display = "";
|
display = "";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tr[i].style.display = display;
|
trs[i].style.display = display;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ class JinjaTemplate:
|
|||||||
"""
|
"""
|
||||||
# idea comes from https://stackoverflow.com/a/38642558
|
# idea comes from https://stackoverflow.com/a/38642558
|
||||||
loader = jinja2.FileSystemLoader(searchpath=self.template_path.parent)
|
loader = jinja2.FileSystemLoader(searchpath=self.template_path.parent)
|
||||||
environment = jinja2.Environment(loader=loader)
|
environment = jinja2.Environment(loader=loader, autoescape=True)
|
||||||
template = environment.get_template(self.template_path.name)
|
template = environment.get_template(self.template_path.name)
|
||||||
|
|
||||||
content = [
|
content = [
|
||||||
|
1
tests/testresources/web/templates
Symbolic link
1
tests/testresources/web/templates
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../package/share/ahriman
|
@ -1,54 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>{{ repository|e }}</title>
|
|
||||||
|
|
||||||
{% include "style.jinja2" %}
|
|
||||||
|
|
||||||
{% include "sorttable.jinja2" %}
|
|
||||||
{% include "search.jinja2" %}
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="root">
|
|
||||||
<h1>ahriman
|
|
||||||
<img src="https://img.shields.io/badge/version-{{ version|e }}-informational" alt="{{ version|e }}">
|
|
||||||
<img src="https://img.shields.io/badge/architecture-{{ architecture|e }}-informational" alt="{{ architecture|e }}">
|
|
||||||
<img src="https://img.shields.io/badge/service%20status-{{ service.status|e }}-{{ service.status_color|e }}" alt="{{ service.status|e }}" title="{{ service.timestamp|e }}">
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
{% include "search-line.jinja2" %}
|
|
||||||
|
|
||||||
<section class="element">
|
|
||||||
<table class="sortable search-table">
|
|
||||||
<tr class="header">
|
|
||||||
<th>package base</th>
|
|
||||||
<th>packages</th>
|
|
||||||
<th>version</th>
|
|
||||||
<th>last update</th>
|
|
||||||
<th>status</th>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
{% for package in packages %}
|
|
||||||
<tr class="package">
|
|
||||||
<td class="include-search"><a href="{{ package.web_url|e }}" title="{{ package.base|e }}">{{ package.base|e }}</a></td>
|
|
||||||
<td class="include-search">{{ package.packages|join("<br>"|safe) }}</td>
|
|
||||||
<td>{{ package.version|e }}</td>
|
|
||||||
<td>{{ package.timestamp|e }}</td>
|
|
||||||
<td class="status package-{{ package.status|e }}">{{ package.status|e }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</table>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<ul class="navigation">
|
|
||||||
<li><a href="https://github.com/arcan1s/ahriman" title="sources">ahriman</a></li>
|
|
||||||
<li><a href="https://github.com/arcan1s/ahriman/releases" title="releases list">releases</a></li>
|
|
||||||
<li><a href="https://github.com/arcan1s/ahriman/issues" title="issues tracker">report a bug</a></li>
|
|
||||||
</ul>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,62 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>{{ repository|e }}</title>
|
|
||||||
|
|
||||||
{% include "style.jinja2" %}
|
|
||||||
|
|
||||||
{% include "sorttable.jinja2" %}
|
|
||||||
{% include "search.jinja2" %}
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="root">
|
|
||||||
<h1>Archlinux user repository</h1>
|
|
||||||
|
|
||||||
<section class="element">
|
|
||||||
{% if pgp_key is not none %}
|
|
||||||
<p>This repository is signed with <a href="http://keys.gnupg.net/pks/lookup?search=0x{{ pgp_key|e }}&fingerprint=on&op=index" title="key search">{{ pgp_key|e }}</a> by default.</p>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<code>
|
|
||||||
$ cat /etc/pacman.conf<br>
|
|
||||||
[{{ repository|e }}]<br>
|
|
||||||
Server = {{ link_path|e }}<br>
|
|
||||||
SigLevel = Database{% if has_repo_signed %}Required{% else %}Never{% endif %} Package{% if has_package_signed %}Required{% else %}Never{% endif %} TrustedOnly
|
|
||||||
</code>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{% include "search-line.jinja2" %}
|
|
||||||
|
|
||||||
<section class="element">
|
|
||||||
<table class="sortable search-table">
|
|
||||||
<tr class="header">
|
|
||||||
<th>package</th>
|
|
||||||
<th>version</th>
|
|
||||||
<th>archive size</th>
|
|
||||||
<th>installed size</th>
|
|
||||||
<th>build date</th>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
{% for package in packages %}
|
|
||||||
<tr class="package">
|
|
||||||
<td class="include-search"><a href="{{ link_path|e }}/{{ package.filename|e }}" title="{{ package.name|e }}">{{ package.name|e }}</a></td>
|
|
||||||
<td>{{ package.version|e }}</td>
|
|
||||||
<td>{{ package.archive_size|e }}</td>
|
|
||||||
<td>{{ package.installed_size|e }}</td>
|
|
||||||
<td>{{ package.build_date|e }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</table>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<ul class="navigation">
|
|
||||||
{% if homepage is not none %}
|
|
||||||
<li><a href="{{ homepage|e }}" title="homepage">Homepage</a></li>
|
|
||||||
{% endif %}
|
|
||||||
</ul>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,3 +0,0 @@
|
|||||||
<section class="element">
|
|
||||||
<input type="search" id="search" onkeyup="searchInTable()" placeholder="search for package" title="search for package"/>
|
|
||||||
</section>
|
|
@ -1,25 +0,0 @@
|
|||||||
<script type="text/javascript">
|
|
||||||
function searchInTable() {
|
|
||||||
const input = document.getElementById("search");
|
|
||||||
const filter = input.value.toLowerCase();
|
|
||||||
const tables = document.getElementsByClassName("search-table");
|
|
||||||
|
|
||||||
for (let i = 0; i < tables.length; i++) {
|
|
||||||
const tr = tables[i].getElementsByTagName("tr");
|
|
||||||
// from 1 coz of header
|
|
||||||
for (let i = 1; i < tr.length; i++) {
|
|
||||||
let td = tr[i].getElementsByClassName("include-search");
|
|
||||||
let display = "none";
|
|
||||||
for (let j = 0; j < td.length; j++) {
|
|
||||||
if (td[j].tagName.toLowerCase() === "td") {
|
|
||||||
if (td[j].innerHTML.toLowerCase().indexOf(filter) > -1) {
|
|
||||||
display = "";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tr[i].style.display = display;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
@ -1 +0,0 @@
|
|||||||
<script src="https://www.kryogenix.org/code/browser/sorttable/sorttable.js"></script>
|
|
@ -1,136 +0,0 @@
|
|||||||
<style>
|
|
||||||
:root {
|
|
||||||
--color-building: 255, 255, 146;
|
|
||||||
--color-failed: 255, 94, 94;
|
|
||||||
--color-pending: 255, 255, 146;
|
|
||||||
--color-success: 94, 255, 94;
|
|
||||||
--color-unknown: 225, 225, 225;
|
|
||||||
|
|
||||||
--color-header: 200, 200, 255;
|
|
||||||
--color-hover: 255, 255, 225;
|
|
||||||
--color-line-blue: 235, 235, 255;
|
|
||||||
--color-line-white: 255, 255, 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes blink-building {
|
|
||||||
0% { background-color: rgba(var(--color-building), 1.0); }
|
|
||||||
10% { background-color: rgba(var(--color-building), 0.9); }
|
|
||||||
20% { background-color: rgba(var(--color-building), 0.8); }
|
|
||||||
30% { background-color: rgba(var(--color-building), 0.7); }
|
|
||||||
40% { background-color: rgba(var(--color-building), 0.6); }
|
|
||||||
50% { background-color: rgba(var(--color-building), 0.5); }
|
|
||||||
60% { background-color: rgba(var(--color-building), 0.4); }
|
|
||||||
70% { background-color: rgba(var(--color-building), 0.3); }
|
|
||||||
80% { background-color: rgba(var(--color-building), 0.2); }
|
|
||||||
90% { background-color: rgba(var(--color-building), 0.1); }
|
|
||||||
100% { background-color: rgba(var(--color-building), 0.0); }
|
|
||||||
}
|
|
||||||
|
|
||||||
div.root {
|
|
||||||
width: 70%;
|
|
||||||
padding: 15px 15% 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
section.element, footer {
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
code, input, table {
|
|
||||||
width: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
th, td {
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr.package:nth-child(odd) {
|
|
||||||
background-color: rgba(var(--color-line-white), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
tr.package:nth-child(even) {
|
|
||||||
background-color: rgba(var(--color-line-blue), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
tr.package:hover {
|
|
||||||
background-color: rgba(var(--color-hover), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
tr.header{
|
|
||||||
background-color: rgba(var(--color-header), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
td.status {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
td.package-unknown {
|
|
||||||
background-color: rgba(var(--color-unknown), 1.0);
|
|
||||||
}
|
|
||||||
td.package-pending {
|
|
||||||
background-color: rgba(var(--color-pending), 1.0);
|
|
||||||
}
|
|
||||||
td.package-building {
|
|
||||||
background-color: rgba(var(--color-building), 1.0);
|
|
||||||
animation-name: blink-building;
|
|
||||||
animation-duration: 1s;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
animation-direction: alternate;
|
|
||||||
}
|
|
||||||
td.package-failed {
|
|
||||||
background-color: rgba(var(--color-failed), 1.0);
|
|
||||||
}
|
|
||||||
td.package-success {
|
|
||||||
background-color: rgba(var(--color-success), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
li.service-unknown {
|
|
||||||
background-color: rgba(var(--color-unknown), 1.0);
|
|
||||||
}
|
|
||||||
li.service-building {
|
|
||||||
background-color: rgba(var(--color-building), 1.0);
|
|
||||||
animation-name: blink-building;
|
|
||||||
animation-duration: 1s;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
animation-direction: alternate;
|
|
||||||
}
|
|
||||||
li.service-failed {
|
|
||||||
background-color: rgba(var(--color-failed), 1.0);
|
|
||||||
}
|
|
||||||
li.service-success {
|
|
||||||
background-color: rgba(var(--color-success), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.navigation {
|
|
||||||
list-style-type: none;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: rgba(var(--color-header), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.navigation li {
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.navigation li.status {
|
|
||||||
display: block;
|
|
||||||
text-align: center;
|
|
||||||
text-decoration: none;
|
|
||||||
padding: 14px 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.navigation li a {
|
|
||||||
display: block;
|
|
||||||
color: black;
|
|
||||||
text-align: center;
|
|
||||||
text-decoration: none;
|
|
||||||
padding: 14px 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.navigation li a:hover {
|
|
||||||
background-color: rgba(var(--color-hover), 1.0);
|
|
||||||
}
|
|
||||||
</style>
|
|
Loading…
Reference in New Issue
Block a user