This is an automated email from the ASF dual-hosted git repository.
sbp pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-atr-experiments.git
The following commit(s) were added to refs/heads/main by this push:
new f1a1222 Improve style
f1a1222 is described below
commit f1a1222049b7ac0cf5bdb792fb4aec780a7cdc47
Author: Sean B. Palmer <[email protected]>
AuthorDate: Mon Feb 17 17:18:57 2025 +0200
Improve style
---
atr/server.py | 3 +
atr/static/css/atr.css | 199 ++++++++++++++
atr/static/css/normalize.css | 405 ++++++++++++++++++++++++++++
atr/static/css/root.css | 4 +
atr/static/webfonts/inter-v.woff2 | Bin 0 -> 352240 bytes
atr/static/webfonts/jost-v.woff2 | Bin 0 -> 50396 bytes
atr/templates/add-release-candidate.html | 209 +++++++-------
atr/templates/data-browser.html | 162 +++++------
atr/templates/includes/footer.html | 9 +-
atr/templates/includes/sidebar.html | 44 +++
atr/templates/layouts/base.html | 31 ++-
atr/templates/release-signature-verify.html | 324 +++++++++++-----------
atr/templates/user-uploads.html | 164 +++++------
13 files changed, 1118 insertions(+), 436 deletions(-)
diff --git a/atr/server.py b/atr/server.py
index c2a563f..e3e80d0 100644
--- a/atr/server.py
+++ b/atr/server.py
@@ -48,6 +48,9 @@ def create_app() -> QuartApp:
raise ValueError("asfquart.construct is not set")
app = asfquart.construct(__name__)
+ # # Configure static folder path before changing working directory
+ # app.static_folder =
os.path.join(os.path.dirname(os.path.abspath(__file__)), "static")
+
@app.context_processor
async def app_wide():
return {"current_user": await asfquart.session.read()}
diff --git a/atr/static/css/atr.css b/atr/static/css/atr.css
new file mode 100644
index 0000000..baa1218
--- /dev/null
+++ b/atr/static/css/atr.css
@@ -0,0 +1,199 @@
+@font-face {
+ font-family: "Jost";
+ src: url("../webfonts/jost-v.woff2") format("woff2");
+ font-weight: 100 900;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: Inter;
+ src: url("../webfonts/inter-v.woff2") format("woff2");
+ font-weight: 100 900;
+ font-style: normal;
+}
+
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+body {
+ font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe
UI', Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
+ -webkit-font-smoothing: antialiased;
+ font-size: 17px;
+ line-height: 24px;
+ font-variation-settings: "opsz" 22;
+ font-weight: 425;
+}
+
+input, textarea, button {
+ font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe
UI', Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
+ font-size: 17px;
+ line-height: 24px;
+ font-variation-settings: "opsz" 22;
+ font-weight: 425;
+}
+
+a { font-weight: 475; }
+
+h1, h2, h3 {
+ font-weight: 475;
+ font-family: Jost;
+}
+
+aside h1 {
+ font-size: 3rem;
+ line-height: 1.15;
+ text-align: center;
+}
+
+aside h1 span {
+ color: #777;
+}
+
+.site-title {
+ text-decoration: none;
+ color: inherit;
+}
+
+h1 { margin-bottom: 2rem; }
+h2, h3, p, ul { margin-bottom: 1rem; }
+
+footer {
+ padding: 2rem;
+ background: #eee;
+ font-size: 15px;
+ margin: 2rem;
+ color: #333;
+}
+
+.wrapper {
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+}
+
+.ribbon {
+ height: 8px;
+ background: linear-gradient(90deg, #282661 0%, #662f8f 20%, #9e2165 40%,
#cb2138 60%, #ea7826 80%, #f7ae18 100%);
+}
+
+.content {
+ flex: 1;
+ display: flex;
+}
+
+.main-container {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+}
+
+.main-content {
+ flex: 1;
+ padding: 2rem;
+}
+
+.sidebar {
+ width: 250px;
+ background-color: #f6f7f8;
+ border-right: 1px solid #d1d2d3;
+ padding: 1rem;
+}
+
+.sidebar .user-section {
+ margin-bottom: 1.5rem;
+ text-align: center;
+ border-top: 1px solid #d1d2d3;
+ border-bottom: 1px solid #d1d2d3;
+ padding: 1.5rem 0;
+}
+
+.sidebar hr {
+ border: none;
+ border-top: 1px solid #999;
+ margin: 1.5rem auto;
+ width: 62%;
+ height: 0;
+}
+
+.sidebar nav {
+ margin-top: 1.5rem;
+}
+
+.sidebar nav ul {
+ list-style: none;
+}
+
+.sidebar nav li {
+ margin-bottom: 1rem;
+}
+
+.hamburger {
+ display: none;
+ background: none;
+ border: none;
+ cursor: pointer;
+ padding: 0;
+ z-index: 100;
+}
+
+.hamburger span {
+ display: block;
+ width: 25px;
+ height: 3px;
+ background-color: #333;
+ margin: 5px 0;
+ transition: 0.3s;
+}
+
+.nav-toggle {
+ display: none;
+}
+
+@media (max-width: 768px) {
+ .hamburger {
+ display: block;
+ position: fixed;
+ top: 20px;
+ padding-left: 2rem;
+ transition: 0.3s;
+ }
+
+ .sidebar {
+ position: fixed;
+ left: -250px;
+ top: 20px;
+ bottom: 0;
+ transition: 0.3s;
+ z-index: 99;
+ }
+
+ /* Show sidebar when checkbox is checked */
+ .nav-toggle:checked ~ .sidebar {
+ left: 0;
+ }
+
+ /* Move hamburger with sidebar */
+ .nav-toggle:checked ~ .hamburger {
+ padding-left: calc(250px + 2rem); /* sidebar width + padding */
+ }
+
+ .nav-toggle:checked ~ .hamburger span:nth-child(1) {
+ transform: rotate(45deg) translate(5px, 5px);
+ }
+
+ .nav-toggle:checked ~ .hamburger span:nth-child(2) {
+ opacity: 0;
+ }
+
+ .nav-toggle:checked ~ .hamburger span:nth-child(3) {
+ transform: rotate(-45deg) translate(7px, -7px);
+ }
+
+ .main-content {
+ margin-left: 0;
+ padding-top: 4rem;
+ }
+}
diff --git a/atr/static/css/normalize.css b/atr/static/css/normalize.css
new file mode 100644
index 0000000..46ab2ba
--- /dev/null
+++ b/atr/static/css/normalize.css
@@ -0,0 +1,405 @@
+
+
+<!doctype html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="viewport" content="width=device-width, initial-scale=1,
viewport-fit=cover">
+
+ <meta property="og:url" content="https://classic.yarnpkg.com/en/package/"
/>
+ <meta property="og:site_name" content="Yarn"/>
+ <meta property="og:title" content="Yarn" />
+ <meta property="og:image"
content="https://classic.yarnpkg.com/assets/og_image.png" />
+ <meta property="og:description" content="Fast, reliable, and secure
dependency management." />
+
+ <title>Yarn</title>
+ <meta name="description" content="Fast, reliable, and secure dependency
management.">
+
+ <link rel="canonical" href="https://classic.yarnpkg.com/lang/en/package/">
+ <link rel="icon" href="/favicon.ico" type="image/x-icon">
+
+ <link rel="search" href="/opensearch.xml"
type="application/opensearchdescription+xml" title="Yarn">
+
+
+ <link rel="stylesheet" href="/css/main.css?t=2024-11-25T15:06:54+00:00">
+ <meta name="google-site-verification"
content="DIcCyEkVaGHm864NWzItnt2n6Gg7hz3l47RBIRyxvcQ" />
+ </head>
+ <body>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<div class="news-container">
+ <a class="news-overlay"
href="https://yarnpkg.com/getting-started/migration"></a>
+
+ <div class="news-inner">
+ <div class="news-line">
+ <span class="news-highlight">Important:</span> This documentation covers
Yarn 1 (Classic).
+ </div>
+ <div class="news-line">
+ For Yarn 2+ docs and migration guide, see yarnpkg.com.
+ </div>
+ </div>
+</div>
+
+
+
+
+<nav class="navbar navbar-static-top navbar-light">
+ <div class="container">
+ <a href="/en/">
+ <svg class="logo navbar-logo" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1154.8 518">
+ <defs>
+ <path id="main" d="
+ M718.6 257.8c-8 27.6-20.8 47.6-35.2
63.6V181c0-9.6-8.4-17.6-21.6-17.6-5.6 0-10.4 2.8-10.4 6.8 0 2.8 1.6 5.2 1.6
12.8v64.4c-4.8 28-16.8 54-32.8 54-11.6 0-18.4-11.6-18.4-33.2 0-33.6 4.4-51.2
11.6-80.8 1.6-6 13.2-22-6.4-22-21.2 0-18.4 8-21.2 14.8 0 0-13.4 47.6-13.4 90 0
34.8 14.6 57.6 41.4 57.6 17.2 0 29.6-11.6 39.2-27.6V351c-26.4 23.2-49.6
43.6-49.6 84 0 25.6 16 46 38.4 46 20.4 0 41.6-14.8 41.6-56.8V355c21.6-18.8
44.8-42.4 58.4-88.8.4-1.6.4-3.6.4-4 0-7.6-7.6-16.4-14-16.4-4 0-7.2 3.6- [...]
+ M833.4 301c-9.6 0-13.6-9.6-13.6-18.4v-66c0-9.6-8.4-17.6-21.6-17.6-5.6
0-10.4 2.8-10.4 6.8 0 2.8 1.6 5.2 1.6 12.8v61.6C785 291.4 777.8 301 767 301c-14
0-22.8-12-22.8-32.8 0-57.6 35.6-83.6 66-83.6 4 0 8 .8 11.6.8 4 0 5.2-2.4
5.2-9.2 0-10.4-7.6-16.8-18.4-16.8-48.8 0-95.2 40.8-95.2 107.6 0 34 16.4 60.4
47.6 60.4 15.2 0 26.4-7.2 34.4-16.4 6 9.6 16.8 16.4 30.8 16.4 34.4 0 50.4-36
57.2-62.4.4-1.6.4-2.4.4-2.8 0-7.6-7.6-16.4-14-16.4-4 0-8 3.6-9.6 12-3.6
17.6-10.8 43.2-26.8 43.2z
+ M949 327.4c34.4 0 50-36 57.2-62.4 0-.8.4-1.6.4-2.8
0-7.6-7.6-16.4-14-16.4-4 0-8 3.6-9.6 12-3.6 17.6-10.4 43.2-28.8 43.2-10.8
0-16-10.4-16-21.6 0-40 18-87.2 18-92 1.6-9.2-14.4-22.4-19.2-22.4h-20.8c-4 0-8
0-21.2-1.6-4.4-16.4-15.6-21.2-25.2-21.2-10.4 0-20 7.2-20 18.4 0 11.6 7.2 20
17.2 25.6-.4 20.4-2 53.6-6.4 69.6-3.6 13.6 17.2 28 22.4 11.2 7.2-23.2 9.6-58
10-73.6h34.8c-12.8 34.4-20 62.8-20 88.4 0 35.2 22.4 45.6 41.2 45.6z
+ M984.6 309.8c0 14.8 11.2 17.6 19.2 17.6 11.6 0 11.2-9.6
11.2-17.2v-58.4c2.8-31.6 27.6-66 39.2-66 7.6 0 8.4 10.4 8.4 22.8v81.2c0 20.4
12.4 37.6 33.6 37.6 34.4 0 51.4-36 58.2-62.4.4-1.6.4-2.4.4-2.8
0-7.6-7.6-16.4-14-16.4-4 0-8 3.6-9.6 12-3.6 17.6-11.8 43.2-27.8 43.2-10.4
0-10.4-14.8-10.4-18.4v-82.8c0-18.4-6.4-40.4-33.2-40.4-19.6 0-34 17.2-44.8
39.6v-18c0-9.6-8.4-17.6-21.6-17.6-5.6 0-10.4 2.8-10.4 6.8 0 2.8 1.6 5.2 1.6
12.8v126.8z
+ M259 0c143 0 259 116 259 259S402 518 259 518 0 402 0 259 116 0 259 0z"/>
+ </defs>
+
+ <use class="logo-primary" xlink:href="#main" x="0" y="0"/>
+
+ <path class="logo-secondary" d="M435.2 337.5c-1.8-14.2-13.8-24-29.2-23.8-23
.3-42.3 12.2-55.1 20.1-5 3.1-9.3 5.4-13
7.1.8-11.6.1-26.8-5.9-43.5-7.3-20-17.1-32.3-24.1-39.4 8.1-11.8 19.2-29
24.4-55.6 4.5-22.7
3.1-58-7.2-77.8-2.1-4-5.6-6.9-10-8.1-1.8-.5-5.2-1.5-11.9.4C293.1 96 289.6 93.8
286.9 92c-5.6-3.6-12.2-4.4-18.4-2.1-8.3 3-15.4 11-22.1 25.2-1 2.1-1.9 4.1-2.7
6.1-12.7.9-32.7 5.5-49.6 23.8-2.1 2.3-6.2 4-10.5 5.6h.1c-8.8 3.1-12.8 10.3-17.7
23.3-6.8 18.2.2 36.1 7.1 47.7-9.4 8.4-21.9 21.8 [...]
+</svg>
+
+ <span class="sr-only">Yarn</span>
+ </a>
+
+ <div class="clearfix hidden-lg-up">
+ <button class="navbar-toggler hidden-lg-up float-right" type="button"
data-toggle="collapse" data-target="#navbar" aria-controls="exCollapsingNavbar2"
+ aria-expanded="false" aria-label="Toggle navigation"></button>
+ </div>
+
+ <div class="collapse navbar-toggleable-md" id="navbar">
+ <ul class="nav navbar-nav">
+ <li class="nav-item">
+ <a class="nav-link" href="/en/docs/getting-started">Getting
Started</a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" href="/en/docs">Docs</a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" href="/en/packages">Packages</a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" href="/blog">Blog</a>
+ </li>
+ </ul>
+
+ <ul class="nav navbar-nav navbar-nav-right float-lg-right">
+
+ <li class="nav-item dropdown">
+ <a id="dropdownNavLanguage" class="nav-link dropdown-toggle"
role="button" href="#" data-toggle="dropdown" aria-haspopup="true"
+ aria-expanded="false">
+ <svg class="language navbar-icon"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
+ <path d="M19.753 10.909c-.624-1.707-2.366-2.726-4.661-2.726-.09
0-.176.002-.262.006l-.016-2.063
3.525-.607c.115-.019.133-.119.109-.231-.023-.111-.167-.883-.188-.976-.027-.131-.102-.127-.207-.109-.104.018-3.25.461-3.25.461l-.013-2.078c-.001-.125-.069-.158-.194-.156l-1.025.016c-.105.002-.164.049-.162.148l.033
2.307s-3.061.527-3.144.543c-.084.014-.17.053-.151.143.019.09.19 1.094.208
1.172.018.08.072.129.188.107l2.924-.504.035 2.018c-1.077.281-1.801.824-2.256
1.303-.768.807-1.207 1.887-1.2 [...]
+</svg>
+ English
+ </a>
+ <div class="dropdown-menu" aria-labelledby="dropdownNavLanguage"
id="dropdownNavLanguageMenu">
+
+ <a href="/en/package" class="dropdown-item active"
+ data-lang="en">
+ English
+ </a>
+
+ <a href="/es-ES/package" class="dropdown-item"
+ data-lang="es">
+ Español
+ </a>
+
+ <a href="/fr/package" class="dropdown-item"
+ data-lang="fr">
+ Français
+ </a>
+
+ <a href="/id-ID/package" class="dropdown-item"
+ data-lang="id">
+ Bahasa Indonesia
+ </a>
+
+ <a href="/ja/package" class="dropdown-item"
+ data-lang="ja">
+ 日本語
+ </a>
+
+ <a href="/pt-BR/package" class="dropdown-item"
+ data-lang="pt-br">
+ Português (Brasil)
+ </a>
+
+ <a href="/ru/package" class="dropdown-item"
+ data-lang="ru">
+ Русский
+ </a>
+
+ <a href="/tr/package" class="dropdown-item"
+ data-lang="tr">
+ Türkçe
+ </a>
+
+ <a href="/uk/package" class="dropdown-item"
+ data-lang="uk">
+ Українська
+ </a>
+
+ <a href="/zh-Hans/package" class="dropdown-item"
+ data-lang="zh-cn">
+ 中文
+ </a>
+
+ <a href="/zh-Hant/package" class="dropdown-item"
+ data-lang="zh-hk">
+ 繁體中文
+ </a>
+
+ </div>
+ </li>
+
+
+ <li class="nav-item">
+ <a class="nav-link" href="https://discord.gg/yarnpkg">
+ <svg class="discord navbar-icon"
xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="discord-svg"
fill="none" viewBox="0 0 71 55">
+ <title id="discord-svg">Discord</title>
+<path d="M60.1045 4.8978C55.5792 2.8214 50.7265 1.2916 45.6527 0.41542C45.5603
0.39851 45.468 0.440769 45.4204 0.525289C44.7963 1.6353 44.105 3.0834 43.6209
4.2216C38.1637 3.4046 32.7345 3.4046 27.3892 4.2216C26.905 3.0581 26.1886
1.6353 25.5617 0.525289C25.5141 0.443589 25.4218 0.40133 25.3294
0.41542C20.2584 1.2888 15.4057 2.8186 10.8776 4.8978C10.8384 4.9147 10.8048
4.9429 10.7825 4.9795C1.57795 18.7309 -0.943561 32.1443 0.293408
45.3914C0.299005 45.4562 0.335386 45.5182 0.385761 45.5 [...]
+</svg>
+
+ <span class="sr-only">Discord</span>
+ </a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" href="https://twitter.com/yarnpkg">
+ <svg class="twitter navbar-icon"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 250 203.1" role="img"
aria-labelledby="twitter-svg">
+ <title id="twitter-svg">Twitter</title>
+ <path d="M78.6 203.1c94.3 0 145.9-78.2 145.9-145.9 0-2.2 0-4.4-.1-6.6 10-7.3
18.7-16.3 25.6-26.5-9.4 4.1-19.3 6.9-29.5 8.1 10.7-6.4 18.7-16.5 22.5-28.4-10.1
6-21.1 10.2-32.6 12.4C191-4.5 158.5-5.5 137.8 14c-13.3 12.5-19 31.2-14.8
49C81.9 60.9 43.4 41.4 17.4 9.4 3.8 32.8 10.7 62.8 33.3
77.8c-8.2-.2-16.1-2.4-23.3-6.4v.6c0 24.4 17.2 45.4 41.2 50.3-7.6 2.1-15.5
2.4-23.2.9 6.7 20.9 26 35.2 47.9 35.6-18.2 14.3-40.6 22-63.7 22-4.1
0-8.2-.3-12.2-.7 23.5 15.1 50.7 23 78.6 23"/>
+</svg>
+
+ <span class="sr-only">Twitter</span>
+ </a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" href="https://www.facebook.com/yarnpkg">
+ <svg class="facebook navbar-icon"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 266.9 266.9" role="img"
aria-labelledby="facebook-svg">
+ <title id="facebook-svg">Facebook</title>
+ <path d="M252.2 0H14.7C6.6 0 0 6.6 0 14.7v237.4c0 8.1 6.6 14.7 14.7
14.7h127.8V163.5h-34.8v-40.3h34.8V93.6c0-34.5 21.1-53.2 51.8-53.2 14.7 0 27.4
1.1 31.1 1.6v36h-21.3c-16.7 0-20 7.9-20 19.6v25.7H224l-5.2
40.3h-34.7V267h68c8.1 0 14.7-6.6 14.7-14.7V14.7c.1-8.1-6.5-14.7-14.6-14.7z"/>
+</svg>
+
+ <span class="sr-only">Facebook</span>
+ </a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" href="https://github.com/yarnpkg">
+ <svg class="github navbar-icon" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 32.6 31.8" role="img" aria-labelledby="github-svg">
+ <title id="github-svg">GitHub</title>
+ <path d="M16.3 0C7.3 0 0 7.3 0 16.3c0 7.2 4.7 13.3 11.1 15.5.8.1 1.1-.4
1.1-.8v-2.8c-4.5 1-5.5-2.2-5.5-2.2-.7-1.9-1.8-2.4-1.8-2.4-1.5-1 .1-1 .1-1 1.6.1
2.5 1.7 2.5 1.7 1.5 2.5 3.8 1.8 4.7 1.4.1-1.1.6-1.8
1-2.2-3.6-.4-7.4-1.8-7.4-8.1 0-1.8.6-3.2 1.7-4.4-.1-.3-.7-2 .2-4.2 0 0 1.4-.4
4.5 1.7 1.3-.4 2.7-.5 4.1-.5 1.4 0 2.8.2 4.1.5 3.1-2.1 4.5-1.7 4.5-1.7.9 2.2.3
3.9.2 4.3 1 1.1 1.7 2.6 1.7 4.4 0 6.3-3.8 7.6-7.4 8 .6.5 1.1 1.5 1.1 3V31c0
.4.3.9 1.1.8 6.5-2.2 11.1-8.3 11.1-15.5C32.6 7.3 25.3 [...]
+</svg>
+
+ <span class="sr-only">GitHub</span>
+ </a>
+ </li>
+ </ul>
+ </div>
+ </div>
+</nav>
+
+ <div id="search">
+ <!-- Here to avoid flash of unstyled content on page load -->
+ <div class="ais-InstantSearch-root full-searchbox">
+ <form novalidate="" class="ais-SearchBox">
+ <div role="search" class="ais-SearchBox-form"></div>
+ </form>
+ </div>
+ </div>
+ <main>
+
+
+<div class="hero">
+ <div class="container">
+ <h1 class="hero-text display-4">Package detail</h1>
+ </div>
+</div>
+
+<div class="container">
+
+<div id="pkg-detail">
+ <div data-reactroot="" class="details row">
+ <section class="details-main col-lg-8">
+ <header class="details-main--header">
+ <h2 class="details-main--title d-inline-block m-2">…</h2>
+ <div class="details-main--info d-inline-block m-2"><a
class="ais-Hit-ownerLink" href=""><img width="20" height="20"
class="ais-Hit-ownerAvatar"
src="https://res.cloudinary.com/hilnmyskv/image/fetch/w_40,h_40,f_auto,q_80,fl_lossy/https://avatars3.githubusercontent.com/u/22247014?v=3&s=200"><!--
react-text: 8 --><!-- /react-text --></a>
+ <span
+ class="ais-Hit-popular null" title="0 downloads in the last 30
days">0</span>
+ <!-- react-empty: 10 -->
+ <!-- react-empty: 11 --><span class="ais-Hit-version"></span></div>
+ <div>
+ <p class="m-2 lead">…</p>
+ </div>
+ <!-- react-empty: 15 -->
+ </header>
+ <section id="readme" class="details-doc">
+ <h3 class="details-doc--title details-doc--title__readme py-1"><a
href="#readme">readme</a></h3>
+ </section>
+ </section>
+ <aside class="details-side col-lg-4">
+ <article class="details-side--links">
+ <div class="detail-links">
+ <div target="_blank" rel="noopener noreferrer"
class="details-links--link details-links--link__yarn"><img
src="/assets/search/ico-yarn.svg" alt="">
+ <div class="copyable">
+ <div class="copyable--content"><span><a
href="https://yarn.pm/…"><!-- react-text: 28 -->yarn.pm/<!-- /react-text
--><!-- react-text: 29 -->…<!-- /react-text --></a></span></div>
+ <button
+ class="copyable--button user-select-none"><img
src="/assets/detail/ico-copy-default.svg" alt="" class="copyable--button__img">
+ <!-- react-text: 32 -->copy
+ <!-- /react-text -->
+ </button>
+ </div>
+ </div><a target="_blank" rel="noopener noreferrer"
href="https://github.com//" class="details-links--link
details-links--link__github"><img src="/assets/search/ico-github.svg"
alt=""><!-- react-text: 35 -->/<!-- /react-text --></a>
+ <a
+ target="_blank" rel="noopener noreferrer"
href="https://www.npmjs.com/package/…" class="details-links--link
details-links--link__npm"><img src="/assets/search/ico-npm.svg" alt="">
+ <!-- react-text: 38 -->…
+ <!-- /react-text -->
+ </a>
+ </div>
+ </article>
+ <article class="details-side--copy">
+ <h1>Use it</h1>
+ <div class="copyable"><code class="copyable--content"><!-- react-text:
43 -->$ <!-- /react-text --><span><!-- react-text: 45 -->yarn add <!--
/react-text --><!-- react-text: 46 -->…<!-- /react-text --></span></code>
+ <button
+ class="copyable--button user-select-none"><img
src="/assets/detail/ico-copy-default.svg" alt="" class="copyable--button__img">
+ <!-- react-text: 49 -->copy
+ <!-- /react-text -->
+ </button>
+ </div>
+ <div><a class="details-side--runkit" href="https://runkit.com/npm/…"
target="_blank" rel="noopener noreferrer">Try in RunKit</a>
+ <!-- react-text: 52 -->·
+ <!-- /react-text --><a href="#">Browse Files</a></div>
+ </article>
+ <article class="details-side--cdns">
+ <h1>CDNs</h1>
+ <dl></dl>
+ </article>
+ <article class="details-side--popularity">
+ <h1>Popularity</h1>
+ <dl></dl>
+ </article>
+ <!-- react-text: 57 -->
+ <!-- /react-text -->
+ <article class="details-side--usage">
+ <h1>Usage</h1>
+ <dl>
+ <div class="d-flex justify-items-between w-100"><img
src="/assets/detail/ico-dependencies.svg" alt="">
+ <dt>Dependencies</dt><span class="dotted flex-grow"></span>
+ <dd>0</dd>
+ </div>
+ <div class="d-flex justify-items-between w-100"><img
src="/assets/detail/ico-devdependencies.svg" alt="">
+ <dt>DevDependencies</dt><span class="dotted flex-grow"></span>
+ <dd>0</dd>
+ </div>
+ <div class="d-flex justify-items-between w-100"><img
src="/assets/detail/ico-package-json.svg" alt="">
+ <dt>Packages</dt><span class="dotted flex-grow"></span>
+ <dd><a target="_blank" rel="noopener noreferrer"
href="https://github.com///tree/master/package.json">see package.json</a></dd>
+ </div>
+ </dl>
+ </article>
+ <article class="details-side--versions">
+ <h1>Versions</h1>
+ <dl></dl>
+ </article>
+ <article class="details-side--contributors">
+ <h1>Contributors</h1>
+ <ul class="list-unstyled m-2">
+ <li class="mb-1">
+ <a class="ais-Hit-ownerLink" href=""><img width="20" height="20"
class="ais-Hit-ownerAvatar"
src="https://res.cloudinary.com/hilnmyskv/image/fetch/w_40,h_40,f_auto,q_80,fl_lossy/https://avatars3.githubusercontent.com/u/22247014?v=3&s=200">
+ <!-- react-text: 86 -->
+ <!-- /react-text -->
+ </a>
+ </li>
+ </ul>
+ </article>
+ </aside>
+ </div>
+</div>
+
+</div>
+</main>
+
+
+
+<hr class="footer-divider">
+
+<div class="container">
+ <footer class="footer">
+ <div class="footer-left">
+ <span class="footer-item">Yarn</span>
+ <span class="footer-item"><a
href="https://github.com/yarnpkg/yarn/blob/master/LICENSE">Distributed under
BSD License</a></span>
+ <span class="footer-item"><a href="/en/org/code-of-conduct">Code of
Conduct</a></span>
+ </div>
+
+ <div class="footer-right">
+
+
+
+ <span class="footer-item"><a
href="https://github.com/yarnpkg/website/edit/master/lang/en/package.html">Edit
this page</a></span>
+
+ </div>
+ </footer>
+</div>
+<script>
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new
Date();a=s.createElement(o),
+
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ ga('create', 'UA-85522875-1', 'auto');
+ ga('send', 'pageview');
+</script>
+
+
+
+<script>
+ var i18n_default = {"search_placeholder":"Search packages (i.e. babel,
webpack, react…)","search_by_algolia":"Search by
Algolia","search_by_read_more":"read how it works","no_package_found":"No
package {name} was found","no_results_docsearch":"Were you looking for
something in the
{documentation_link}?","documentation":"documentation","downloads_in_last_30_days":"{count}
downloads in the last 30 days","npm_page_for":"npm page for
{name}","repository_of":"{provider} repository of {name} [...]
+ window.i18n = {"search_placeholder":"Search packages (i.e. babel, webpack,
react…)","search_by_algolia":"Search by Algolia","search_by_read_more":"read
how it works","no_package_found":"No package {name} was
found","no_results_docsearch":"Were you looking for something in the
{documentation_link}?","documentation":"documentation","downloads_in_last_30_days":"{count}
downloads in the last 30 days","npm_page_for":"npm page for
{name}","repository_of":"{provider} repository of {name}","np [...]
+ window.i18n.url_base = "/en";
+ window.i18n.active_language = "en";
+
+ // give defaults
+ function copyDefaults(from, to) {
+ for (var key in from) {
+ if (from[key] !== null && typeof from[key] === 'object') {
+ copyDefaults(from[key], to[key] || (to[key] = {}));
+ continue;
+ }
+ if (to.hasOwnProperty(key) === false || to[key] === null) {
+ to[key] = from[key];
+ }
+ }
+ }
+
+ copyDefaults(i18n_default, window.i18n);
+</script>
+
+ <script src="/js/build/vendor.bb983233e26fd3fd2fe3.js"></script>
+ <script src="/js/build/common.2a29ed27bfa751cd6609.js"></script>
+
+
+ <script src="/js/build/package.302c84e81c9aeae765da.js"></script>
+
+ </body>
+</html>
diff --git a/atr/static/css/root.css b/atr/static/css/root.css
index 8da932b..3cbc448 100644
--- a/atr/static/css/root.css
+++ b/atr/static/css/root.css
@@ -52,3 +52,7 @@ h1 {
max-width: 800px;
color: #555;
}
+
+.ribbon {
+ background: linear-gradient(90deg, #282661 0%, #662f8f 20%, #9e2165 40%,
#cb2138 60%, #ea7826 80%, #f7ae18 100%);
+}
diff --git a/atr/static/webfonts/inter-v.woff2
b/atr/static/webfonts/inter-v.woff2
new file mode 100644
index 0000000..5a8d3e7
Binary files /dev/null and b/atr/static/webfonts/inter-v.woff2 differ
diff --git a/atr/static/webfonts/jost-v.woff2 b/atr/static/webfonts/jost-v.woff2
new file mode 100644
index 0000000..eedcc3f
Binary files /dev/null and b/atr/static/webfonts/jost-v.woff2 differ
diff --git a/atr/templates/add-release-candidate.html
b/atr/templates/add-release-candidate.html
index d95d582..c8d2d34 100644
--- a/atr/templates/add-release-candidate.html
+++ b/atr/templates/add-release-candidate.html
@@ -1,107 +1,110 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width,initial-scale=1.0" />
- <meta name="description" content="Add a release candidate to the
database." />
- <title>ATR | Add Release Candidate</title>
- <link rel="stylesheet" href="{{ url_for('static', filename='root.css') }}"
/>
- <style>
- .form-group {
- margin-bottom: 1rem;
- }
-
- .form-group label {
- display: block;
- margin-bottom: 0.5rem;
- }
-
- .error-message {
- color: #dc3545;
- margin-top: 0.25rem;
- }
-
- select,
- input[type="file"] {
- display: block;
- margin-bottom: 0.5rem;
- }
-
- small {
- color: #666;
- }
-
- button {
- margin-top: 1rem;
- padding: 0.5rem 1rem;
- }
-
- button:disabled {
- opacity: 0.5;
- cursor: not-allowed;
- }
- </style>
- </head>
- <body>
- <h1>Add Release Candidate</h1>
- <p class="intro">On this page, you can add a release candidate to the
database.</p>
-
- <div class="user-info">
- <p>
- Welcome, <strong>{{ asf_id }}</strong>! You are authenticated as an
ASF committer.
- </p>
-
- {% if pmc_memberships %}
- <h3>Your PMC Memberships:</h3>
- <ul>
- {% for pmc in pmc_memberships %}<li>{{ pmc }}</li>{% endfor %}
- </ul>
- {% endif %}
+{% extends "layouts/base.html" %}
+
+{% block title %}
+ ATR | Add Release Candidate
+{% endblock title %}
+
+{% block description %}
+ Add a release candidate to the database.
+{% endblock description %}
+
+{% block stylesheets %}
+ {{ super() }}
+ <style>
+ .form-group {
+ margin-bottom: 1rem;
+ }
+
+ .form-group label {
+ display: block;
+ margin-bottom: 0.5rem;
+ }
+
+ .error-message {
+ color: #dc3545;
+ margin-top: 0.25rem;
+ }
+
+ select,
+ input[type="file"] {
+ display: block;
+ margin-bottom: 0.5rem;
+ }
+
+ small {
+ color: #666;
+ }
+
+ button {
+ margin-top: 1rem;
+ padding: 0.5rem 1rem;
+ }
- {% if committer_projects %}
- <h3>Your Committer Access:</h3>
- <ul>
- {% for project in committer_projects %}<li>{{ project }}</li>{%
endfor %}
- </ul>
+ button:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+ }
+ </style>
+{% endblock stylesheets %}
+
+{% block content %}
+ <h1>Add Release Candidate</h1>
+ <p class="intro">On this page, you can add a release candidate to the
database.</p>
+
+ <div class="user-info">
+ <p>
+ Welcome, <strong>{{ asf_id }}</strong>! You are authenticated as an ASF
committer.
+ </p>
+
+ {% if pmc_memberships %}
+ <h3>Your PMC Memberships:</h3>
+ <ul>
+ {% for pmc in pmc_memberships %}<li>{{ pmc }}</li>{% endfor %}
+ </ul>
+ {% endif %}
+
+ {% if committer_projects %}
+ <h3>Your Committer Access:</h3>
+ <ul>
+ {% for project in committer_projects %}<li>{{ project }}</li>{% endfor
%}
+ </ul>
+ {% endif %}
+ </div>
+
+ <form method="post" enctype="multipart/form-data">
+ <div class="form-group">
+ <label for="project_name">Project:</label>
+ <select id="project_name" name="project_name" required>
+ <option value="">Select a project...</option>
+ {% for pmc in pmc_memberships %}<option value="{{ pmc }}">{{ pmc
}}</option>{% endfor %}
+ </select>
+ {% if not pmc_memberships %}
+ <p class="error-message">You must be a PMC member to submit a release
candidate.</p>
{% endif %}
</div>
- <form method="post" enctype="multipart/form-data">
- <div class="form-group">
- <label for="project_name">Project:</label>
- <select id="project_name" name="project_name" required>
- <option value="">Select a project...</option>
- {% for pmc in pmc_memberships %}<option value="{{ pmc }}">{{ pmc
}}</option>{% endfor %}
- </select>
- {% if not pmc_memberships %}
- <!-- TODO: Should probably move this up and do if/elif -->
- <p class="error-message">You must be a PMC member to submit a
release candidate.</p>
- {% endif %}
- </div>
-
- <div class="form-group">
- <label for="release_artifact">Release Candidate Archive:</label>
- <input type="file"
- id="release_artifact"
- name="release_artifact"
- required
-
accept="application/gzip,application/x-gzip,application/x-tar,application/zip,application/java-archive,.tar.gz,.tgz,.zip,.jar"
- aria-describedby="artifact-help" />
- <span id="artifact-help">Upload the release candidate archive (tar.gz,
zip, or jar)</span>
- </div>
-
- <div class="form-group">
- <label for="release_signature">Detached GPG Signature:</label>
- <input type="file"
- id="release_signature"
- name="release_signature"
- required
- accept="application/pgp-signature,.asc"
- aria-describedby="signature-help" />
- <span id="signature-help">Upload the detached GPG signature (.asc)
file for the release candidate</span>
- </div>
-
- <button type="submit" {% if not pmc_memberships %}disabled{% endif
%}>Submit Release Candidate</button>
- </form>
- </body>
-</html>
+ <div class="form-group">
+ <label for="release_artifact">Release Candidate Archive:</label>
+ <input type="file"
+ id="release_artifact"
+ name="release_artifact"
+ required
+
accept="application/gzip,application/x-gzip,application/x-tar,application/zip,application/java-archive,.tar.gz,.tgz,.zip,.jar"
+ aria-describedby="artifact-help" />
+ <span id="artifact-help">Upload the release candidate archive (tar.gz,
zip, or jar)</span>
+ </div>
+
+ <div class="form-group">
+ <label for="release_signature">Detached GPG Signature:</label>
+ <input type="file"
+ id="release_signature"
+ name="release_signature"
+ required
+ accept="application/pgp-signature,.asc"
+ aria-describedby="signature-help" />
+ <span id="signature-help">Upload the detached GPG signature (.asc) file
for the release candidate</span>
+ </div>
+
+ <button type="submit" {% if not pmc_memberships %}disabled{% endif
%}>Submit Release Candidate</button>
+ </form>
+{% endblock content %}
diff --git a/atr/templates/data-browser.html b/atr/templates/data-browser.html
index 3281b48..d801071 100644
--- a/atr/templates/data-browser.html
+++ b/atr/templates/data-browser.html
@@ -1,89 +1,93 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width,initial-scale=1.0" />
- <meta name="description" content="Browse all records in the database." />
- <title>ATR | Data Browser</title>
- <link rel="stylesheet" href="{{ url_for('static', filename='root.css') }}"
/>
- <style>
- .model-nav {
- margin: 1rem 0;
- padding: 0.5rem;
- background: #f5f5f5;
- border-radius: 4px;
- }
+{% extends "layouts/base.html" %}
- .model-nav a {
- margin-right: 1rem;
- padding: 0.25rem 0.5rem;
- text-decoration: none;
- color: #333;
- }
+{% block title %}
+ ATR | Data Browser
+{% endblock title %}
- .model-nav a.active {
- background: #333;
- color: white;
- border-radius: 2px;
- }
+{% block description %}
+ Browse all records in the database.
+{% endblock description %}
- .record {
- border: 1px solid #ddd;
- padding: 1rem;
- margin-bottom: 1rem;
- border-radius: 4px;
- }
+{% block stylesheets %}
+ {{ super() }}
+ <style>
+ .model-nav {
+ margin: 1rem 0;
+ padding: 0.5rem;
+ background: #f5f5f5;
+ border-radius: 4px;
+ }
- .record pre {
- background: #f5f5f5;
- padding: 0.5rem;
- border-radius: 2px;
- overflow-x: auto;
- }
+ .model-nav a {
+ margin-right: 1rem;
+ padding: 0.25rem 0.5rem;
+ text-decoration: none;
+ color: #333;
+ }
- .record-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 0.5rem;
- }
+ .model-nav a.active {
+ background: #333;
+ color: white;
+ border-radius: 2px;
+ }
- .record-meta {
- color: #666;
- font-size: 0.9em;
- }
+ .record {
+ border: 1px solid #ddd;
+ padding: 1rem;
+ margin-bottom: 1rem;
+ border-radius: 4px;
+ }
- .no-records {
- color: #666;
- font-style: italic;
- }
- </style>
- </head>
- <body>
- <h1>Data Browser</h1>
- <p class="intro">Browse all records in the database.</p>
+ .record pre {
+ background: #f5f5f5;
+ padding: 0.5rem;
+ border-radius: 2px;
+ overflow-x: auto;
+ }
- <div class="model-nav">
- {% for model_name in models %}
- <a href="{{ url_for('root_admin_database', model=model_name) }}"
- {% if model == model_name %}class="active"{% endif %}>{{ model_name
}}</a>
- {% endfor %}
- </div>
+ .record-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 0.5rem;
+ }
+
+ .record-meta {
+ color: #666;
+ font-size: 0.9em;
+ }
+
+ .no-records {
+ color: #666;
+ font-style: italic;
+ }
+ </style>
+{% endblock stylesheets %}
- {% if records %}
- <div class="records">
- {% for record in records %}
- <div class="record">
- <div class="record-header">
- <h3>{{ record.get('id', record.get('storage_key', 'Unknown ID')
) }}</h3>
- <span class="record-meta">{{ model }}</span>
- </div>
- <pre>{{ record | tojson(indent=2) }}</pre>
+{% block content %}
+ <h1>Data Browser</h1>
+ <p class="intro">Browse all records in the database.</p>
+
+ <div class="model-nav">
+ {% for model_name in models %}
+ <a href="{{ url_for('root_admin_database', model=model_name) }}"
+ {% if model == model_name %}class="active"{% endif %}>{{ model_name
}}</a>
+ {% endfor %}
+ </div>
+
+ {% if records %}
+ <div class="records">
+ {% for record in records %}
+ <div class="record">
+ <div class="record-header">
+ <h3>{{ record.get('id', record.get('storage_key', 'Unknown ID') )
}}</h3>
+ <span class="record-meta">{{ model }}</span>
</div>
- {% endfor %}
- </div>
- {% else %}
- <p class="no-records">No records found for {{ model }}.</p>
- {% endif %}
- </body>
-</html>
+ <pre>{{ record | tojson(indent=2) }}</pre>
+ </div>
+ {% endfor %}
+ </div>
+ {% else %}
+ <p class="no-records">No records found for {{ model }}.</p>
+ {% endif %}
+{% endblock content %}
diff --git a/atr/templates/includes/footer.html
b/atr/templates/includes/footer.html
index 38535c7..e39063a 100644
--- a/atr/templates/includes/footer.html
+++ b/atr/templates/includes/footer.html
@@ -1,5 +1,8 @@
<footer class="footer mt-auto py-3">
- <div class="container">
- <span class="text-muted">Copyright © 2025, The Apache Software Foundation.
Material licensed under the <a
href="https://www.apache.org/licenses/LICENSE-2.0">Apache License, version
2.0</a>. For inquiries, contact [email protected]</span>
- </div>
+ <p class="text-muted">
+ Copyright © 2025, The Apache Software Foundation. Material licensed under
the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License,
version 2.0</a>.
+ </p>
+ <p class="text-muted">
+ For inquiries, contact <a
href="mailto:[email protected]">[email protected]</a>
+ </p>
</footer>
diff --git a/atr/templates/includes/sidebar.html
b/atr/templates/includes/sidebar.html
new file mode 100644
index 0000000..6a230d1
--- /dev/null
+++ b/atr/templates/includes/sidebar.html
@@ -0,0 +1,44 @@
+<aside class="sidebar">
+ <div class="sidebar-header">
+ <a href="{{ url_for('root') }}" class="site-title">
+ <h1>
+ A<span>pache</span>
+ <br />
+ T<span>rusted</span>
+ <br />
+ R<span>elease</span>
+ </h1>
+ </a>
+ </div>
+ <div class="user-section">
+ {% if current_user %}
+ <div class="user-info">
+ <span>{{ current_user.fullname }}</span>
+ (<code>{{ current_user.uid }}</code>)
+ </div>
+ <a href="#"
+ onclick="location.href='/auth?logout=' + window.location.pathname;"
+ class="logout-link">Logout</a>
+ {% else %}
+ <a href="#"
+ onclick="location.href='/auth?login=' + window.location.pathname;"
+ class="login-link">Login</a>
+ {% endif %}
+ </div>
+ <nav>
+ <ul>
+ <li>
+ <a href="{{ url_for('root') }}"
+ {% if request.endpoint == 'root' %}class="active"{% endif
%}>Home</a>
+ </li>
+ <li>
+ <a href="{{ url_for('root_pages') }}"
+ {% if request.endpoint == 'root_pages' %}class="active"{% endif
%}>Pages</a>
+ </li>
+ <li>
+ <a href="{{ url_for('root_pmc_directory') }}"
+ {% if request.endpoint == 'root_pmc_directory' %}class="active"{%
endif %}>PMC Directory</a>
+ </li>
+ </ul>
+ </nav>
+</aside>
diff --git a/atr/templates/layouts/base.html b/atr/templates/layouts/base.html
index 7805157..87880cc 100644
--- a/atr/templates/layouts/base.html
+++ b/atr/templates/layouts/base.html
@@ -11,27 +11,36 @@
</title>
{% block stylesheets %}
<link rel="stylesheet"
- href="{{ url_for('static', filename='css/bootstrap.min.css') }}" />
+ href="{{ url_for('static', filename='css/normalize.css') }}" />
<link rel="stylesheet"
- href="{{ url_for('static', filename='css/fontawesome.all.min.css')
}}" />
- <link rel="stylesheet"
- href="{{ url_for('static', filename='css/root.css') }}" />
+ href="{{ url_for('static', filename='css/atr.css') }}" />
{% endblock stylesheets %}
</head>
<body class="{%- block body_class -%}{%- endblock body_class -%}">
<div class="wrapper">
- {% include "includes/navigation.html" %}
+ <div class="ribbon"></div>
+ <div class="content">
+ <input type="checkbox" id="nav-toggle" class="nav-toggle" />
+ <label for="nav-toggle" class="hamburger" aria-label="Menu">
+ <span class="hamburger-line"></span>
+ <span class="hamburger-line"></span>
+ <span class="hamburger-line"></span>
+ </label>
+
+ {% include "includes/sidebar.html" %}
- {% block content %}
- {% endblock content %}
- {% include "includes/footer.html" %}
+ <div class="main-container">
+ <main class="main-content">
+ {% block content %}
+ {% endblock content %}
+ </main>
+ {% include "includes/footer.html" %}
+ </div>
+ </div>
</div>
{% block javascripts %}
- <script src="{{ url_for('static', filename='js/bootstrap.bundle.min.js')
}}"></script>
-
{% endblock javascripts %}
-
</body>
</html>
diff --git a/atr/templates/release-signature-verify.html
b/atr/templates/release-signature-verify.html
index 39e895c..2b4d14f 100644
--- a/atr/templates/release-signature-verify.html
+++ b/atr/templates/release-signature-verify.html
@@ -1,164 +1,168 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width,initial-scale=1.0" />
- <meta name="description" content="Verify release candidate signatures." />
- <title>ATR | Verify Release Signatures</title>
- <link rel="stylesheet" href="{{ url_for('static', filename='root.css') }}"
/>
- <style>
- .release-info {
- margin-bottom: 2rem;
- }
-
- .package-list {
- margin: 1rem 0;
- }
-
- .package {
- border: 1px solid #ddd;
- padding: 1rem;
- margin: 1rem 0;
- border-radius: 4px;
- }
-
- .package-info {
- margin-bottom: 1rem;
- }
-
- .verification-status {
- margin-top: 1rem;
- padding: 1rem;
- border-radius: 4px;
- background: #f5f5f5;
- }
-
- .navigation {
- margin-top: 2rem;
- }
-
- .navigation a {
- margin-right: 1rem;
- }
-
- .error {
- color: #dc3545;
- font-weight: bold;
- }
-
- .status.success {
- color: #28a745;
- }
-
- .status.failure {
- color: #dc3545;
- }
-
- .signature-details {
- margin-top: 1rem;
- padding: 1rem;
- border-radius: 4px;
- background: #f5f5f5;
- }
-
- .debug-info {
- margin-top: 1rem;
- padding: 1rem;
- border-radius: 4px;
- background: #f8f9fa;
- border: 1px solid #dee2e6;
- }
-
- .debug-info h3 {
- margin-top: 0;
- color: #666;
- }
-
- .debug-info dl {
- margin: 0;
- display: grid;
- grid-template-columns: auto 1fr;
- gap: 0.5rem 1rem;
- }
-
- .debug-info dt {
- font-weight: bold;
- color: #666;
- }
-
- .debug-info dd {
- margin: 0;
- word-break: break-all;
- }
-
- pre.stderr {
- background: #f8f9fa;
- padding: 0.5rem;
- border-radius: 2px;
- overflow-x: auto;
- margin: 0.5rem 0;
- white-space: pre-wrap;
- }
- </style>
- </head>
- <body>
- <h1>Verify Release Signatures</h1>
-
- <div class="release-info">
- <h2>{{ release.pmc.project_name }}</h2>
- <p>
- Stage: {{ release.stage.value }}
- •
- Phase: {{ release.phase.value }}
- </p>
- </div>
-
- <div class="package-list">
- {% for result in verification_results %}
- <div class="package">
- <div class="package-info">
- <div>File: {{ result.file }}</div>
- </div>
-
- <div class="verification-status">
- {% if result.error %}
- <p class="error">Error: {{ result.error }}</p>
- {% else %}
- <p class="status {% if result.verified %}success{% else
%}failure{% endif %}">Status: {{ result.status }}</p>
- {% if result.verified %}
- <div class="signature-details">
- <p>Key ID: {{ result.key_id }}</p>
- <p>Signed by: {{ result.username }} <{{ result.email
}}></p>
- <p>Timestamp: {{ result.timestamp }}</p>
- </div>
- {% endif %}
- {% endif %}
+{% extends "layouts/base.html" %}
+
+{% block title %}
+ ATR | Verify Release Signatures
+{% endblock title %}
+
+{% block description %}
+ Verify release candidate signatures.
+{% endblock description %}
+
+{% block stylesheets %}
+ {{ super() }}
+ <style>
+ .release-info {
+ margin-bottom: 2rem;
+ }
+
+ .package-list {
+ margin: 1rem 0;
+ }
+
+ .package {
+ border: 1px solid #ddd;
+ padding: 1rem;
+ margin: 1rem 0;
+ border-radius: 4px;
+ }
+
+ .package-info {
+ margin-bottom: 1rem;
+ }
+
+ .verification-status {
+ margin-top: 1rem;
+ padding: 1rem;
+ border-radius: 4px;
+ background: #f5f5f5;
+ }
+
+ .navigation {
+ margin-top: 2rem;
+ }
+
+ .navigation a {
+ margin-right: 1rem;
+ }
+
+ .error {
+ color: #dc3545;
+ font-weight: bold;
+ }
+
+ .status.success {
+ color: #28a745;
+ }
+
+ .status.failure {
+ color: #dc3545;
+ }
+
+ .signature-details {
+ margin-top: 1rem;
+ padding: 1rem;
+ border-radius: 4px;
+ background: #f5f5f5;
+ }
+
+ .debug-info {
+ margin-top: 1rem;
+ padding: 1rem;
+ border-radius: 4px;
+ background: #f8f9fa;
+ border: 1px solid #dee2e6;
+ }
+
+ .debug-info h3 {
+ margin-top: 0;
+ color: #666;
+ }
+
+ .debug-info dl {
+ margin: 0;
+ display: grid;
+ grid-template-columns: auto 1fr;
+ gap: 0.5rem 1rem;
+ }
+
+ .debug-info dt {
+ font-weight: bold;
+ color: #666;
+ }
+
+ .debug-info dd {
+ margin: 0;
+ word-break: break-all;
+ }
+
+ pre.stderr {
+ background: #f8f9fa;
+ padding: 0.5rem;
+ border-radius: 2px;
+ overflow-x: auto;
+ margin: 0.5rem 0;
+ white-space: pre-wrap;
+ }
+ </style>
+{% endblock stylesheets %}
+
+{% block content %}
+ <h1>Verify Release Signatures</h1>
+
+ <div class="release-info">
+ <h2>{{ release.pmc.project_name }}</h2>
+ <p>
+ Stage: {{ release.stage.value }}
+ •
+ Phase: {{ release.phase.value }}
+ </p>
+ </div>
+
+ <div class="package-list">
+ {% for result in verification_results %}
+ <div class="package">
+ <div class="package-info">
+ <div>File: {{ result.file }}</div>
+ </div>
- {% if result.debug_info %}
- <div class="debug-info">
- <h3>Debug Information</h3>
- <dl>
- {% for key, value in result.debug_info.items() %}
- <dt>{{ key }}</dt>
- <dd>
- {% if key == 'stderr' and value != 'Not available' %}
- <pre class="stderr">{{ value }}</pre>
- {% else %}
- {{ value }}
- {% endif %}
- </dd>
- {% endfor %}
- </dl>
+ <div class="verification-status">
+ {% if result.error %}
+ <p class="error">Error: {{ result.error }}</p>
+ {% else %}
+ <p class="status {% if result.verified %}success{% else
%}failure{% endif %}">Status: {{ result.status }}</p>
+ {% if result.verified %}
+ <div class="signature-details">
+ <p>Key ID: {{ result.key_id }}</p>
+ <p>Signed by: {{ result.username }} <{{ result.email
}}></p>
+ <p>Timestamp: {{ result.timestamp }}</p>
</div>
{% endif %}
- </div>
+ {% endif %}
+
+ {% if result.debug_info %}
+ <div class="debug-info">
+ <h3>Debug Information</h3>
+ <dl>
+ {% for key, value in result.debug_info.items() %}
+ <dt>{{ key }}</dt>
+ <dd>
+ {% if key == 'stderr' and value != 'Not available' %}
+ <pre class="stderr">{{ value }}</pre>
+ {% else %}
+ {{ value }}
+ {% endif %}
+ </dd>
+ {% endfor %}
+ </dl>
+ </div>
+ {% endif %}
</div>
- {% endfor %}
- </div>
-
- <div class="navigation">
- <a href="{{ url_for('root_user_uploads') }}">Back to Your Uploads</a>
- <a href="{{ url_for('root_pages') }}">Return to Main Page</a>
- </div>
- </body>
-</html>
+ </div>
+ {% endfor %}
+ </div>
+
+ <div class="navigation">
+ <a href="{{ url_for('root_user_uploads') }}">Back to Your Uploads</a>
+ <a href="{{ url_for('root_pages') }}">Return to Main Page</a>
+ </div>
+{% endblock content %}
diff --git a/atr/templates/user-uploads.html b/atr/templates/user-uploads.html
index 363b2db..ed36f60 100644
--- a/atr/templates/user-uploads.html
+++ b/atr/templates/user-uploads.html
@@ -1,89 +1,93 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width,initial-scale=1.0" />
- <meta name="description" content="Your uploaded release candidates." />
- <title>ATR | Your Uploads</title>
- <link rel="stylesheet" href="{{ url_for('static', filename='root.css') }}"
/>
- <style>
- .release-list {
- margin: 1rem 0;
- }
+{% extends "layouts/base.html" %}
- .release {
- border: 1px solid #ddd;
- padding: 1rem;
- margin-bottom: 1rem;
- border-radius: 4px;
- }
+{% block title %}
+ ATR | Your Uploads
+{% endblock title %}
- .release-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 0.5rem;
- }
+{% block description %}
+ Your uploaded release candidates.
+{% endblock description %}
- .release-meta {
- color: #666;
- font-size: 0.9em;
- }
+{% block stylesheets %}
+ {{ super() }}
+ <style>
+ .release-list {
+ margin: 1rem 0;
+ }
- .package-list {
- margin-top: 0.5rem;
- }
+ .release {
+ border: 1px solid #ddd;
+ padding: 1rem;
+ margin-bottom: 1rem;
+ border-radius: 4px;
+ }
- .package {
- background: #f5f5f5;
- padding: 0.5rem;
- margin: 0.25rem 0;
- border-radius: 2px;
- }
+ .release-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 0.5rem;
+ }
- .no-releases {
- color: #666;
- font-style: italic;
- }
- </style>
- </head>
- <body>
- <h1>Your Uploads</h1>
- <p class="intro">Here are all the release candidates you've uploaded.</p>
+ .release-meta {
+ color: #666;
+ font-size: 0.9em;
+ }
- {% if releases %}
- <div class="release-list">
- {% for release in releases %}
- <div class="release">
- <div class="release-header">
- <h3>{{ release.pmc.project_name }}</h3>
- <span class="release-meta">
- Stage: {{ release.stage.value }}
- •
- Phase: {{ release.phase.value }}
- </span>
- </div>
- <div class="package-list">
- {% for package in release.packages %}
- <div class="package">
- <div>File: {{ package.file }}</div>
- <div>Signature: {{ package.signature }}</div>
- <div>Checksum (SHA-512): {{ package.checksum }}</div>
- <p class="package-actions">
- <a href="{{ url_for('root_release_signatures_verify',
release_key=release.storage_key) }}">Verify Signatures</a>
- </p>
- </div>
- {% endfor %}
- </div>
+ .package-list {
+ margin-top: 0.5rem;
+ }
+
+ .package {
+ background: #f5f5f5;
+ padding: 0.5rem;
+ margin: 0.25rem 0;
+ border-radius: 2px;
+ }
+
+ .no-releases {
+ color: #666;
+ font-style: italic;
+ }
+ </style>
+{% endblock stylesheets %}
+
+{% block content %}
+ <h1>Your Uploads</h1>
+ <p class="intro">Here are all the release candidates you've uploaded.</p>
+
+ {% if releases %}
+ <div class="release-list">
+ {% for release in releases %}
+ <div class="release">
+ <div class="release-header">
+ <h3>{{ release.pmc.project_name }}</h3>
+ <span class="release-meta">
+ Stage: {{ release.stage.value }}
+ •
+ Phase: {{ release.phase.value }}
+ </span>
+ </div>
+ <div class="package-list">
+ {% for package in release.packages %}
+ <div class="package">
+ <div>File: {{ package.file }}</div>
+ <div>Signature: {{ package.signature }}</div>
+ <div>Checksum (SHA-512): {{ package.checksum }}</div>
+ <p class="package-actions">
+ <a href="{{ url_for('root_release_signatures_verify',
release_key=release.storage_key) }}">Verify Signatures</a>
+ </p>
+ </div>
+ {% endfor %}
</div>
- {% endfor %}
- </div>
- {% else %}
- <p class="no-releases">You haven't uploaded any release candidates
yet.</p>
- {% endif %}
+ </div>
+ {% endfor %}
+ </div>
+ {% else %}
+ <p class="no-releases">You haven't uploaded any release candidates yet.</p>
+ {% endif %}
- <p>
- <a href="{{ url_for('root_add_release_candidate') }}">Upload a new
release candidate</a>
- </p>
- </body>
-</html>
+ <p>
+ <a href="{{ url_for('root_add_release_candidate') }}">Upload a new release
candidate</a>
+ </p>
+{% endblock content %}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]