diff options
| -rwxr-xr-x | buildsite.sh | 278 | ||||
| -rw-r--r-- | files/footer | 4 | ||||
| -rw-r--r-- | files/header | 200 | ||||
| -rw-r--r-- | readme.md | 1 |
4 files changed, 360 insertions, 123 deletions
diff --git a/buildsite.sh b/buildsite.sh index 6e24206d..ab604e73 100755 --- a/buildsite.sh +++ b/buildsite.sh @@ -23,72 +23,6 @@ port_depends() { generate_ports_page() { { sed "s/@TITLE@/ports/g" files/header - cat << 'EOF' -<style> -.ports-toolbar { - display: flex; - flex-wrap: wrap; - gap: 8px; - margin-bottom: 12px; -} -.ports-toolbar button, -.ports-toolbar input { - font: inherit; - color: #fefefe; - background: transparent; - border: 0; - border-bottom: 1px solid rgba(231, 232, 235, 0.35); - padding: 6px 0; -} -.ports-toolbar button { - cursor: pointer; -} -.ports-toolbar button.active { - color: #90cbf9; - border-bottom-color: #90cbf9; -} -.ports-toolbar input { - flex: 1 1 18em; - min-width: 0; -} -.ports-count { - margin-bottom: 12px; -} -#ports-table th, -#ports-table td { - border: 0; - border-bottom: 1px solid rgba(231, 232, 235, 0.28); - padding: 6px 4px; -} -#ports-table { - border: 0; - table-layout: auto; -} -#ports-table thead th { - border-bottom-color: rgba(231, 232, 235, 0.55); -} -#ports-table th:nth-child(1), -#ports-table td:nth-child(1) { - width: 5em; -} -#ports-table th:nth-child(2), -#ports-table td:nth-child(2) { - width: 16em; -} -#ports-table th:nth-child(3), -#ports-table td:nth-child(3) { - white-space: nowrap; - width: 1%; -} -#ports-table th:nth-child(4), -#ports-table td:nth-child(4) { - width: 100%; -} -#ports-table tbody tr:last-child td { - border-bottom: 0; -} -EOF - echo "</style>" echo "<p>Package ports generated from <code>repos/core</code>, <code>repos/extra</code>, and <code>repos/community</code>.</p>" echo "<div class=\"ports-toolbar\">" echo "<button type=\"button\" class=\"active\" data-repo=\"all\">all</button>" @@ -187,6 +121,218 @@ done generate_ports_page +generate_commits_page() { + { + sed "s/@TITLE@/commits/g" files/header + cat << 'EOF' +<p>Recent commits from <a href="https://codeberg.org/emmett1/alicelinux">codeberg.org/emmett1/alicelinux</a>.</p> +<ul id="commits"></ul> +<div id="commits-loading">loading…</div> +<div id="commits-error"></div> +<script> +(function () { + var list = document.getElementById('commits'); + var loading = document.getElementById('commits-loading'); + var errEl = document.getElementById('commits-error'); + var page = 1; + var loadingMore = false; + var hasMore = true; + var PER_PAGE = 30; + + function fmtHash(hash) { + return hash.substring(0, 7); + } + + function fmtDate(iso) { + var d = new Date(iso); + var y = d.getFullYear(); + var m = String(d.getMonth() + 1).padStart(2, '0'); + var day = String(d.getDate()).padStart(2, '0'); + var h = String(d.getHours()).padStart(2, '0'); + var min = String(d.getMinutes()).padStart(2, '0'); + return y + '-' + m + '-' + day + ' ' + h + ':' + min; + } + + function esc(s) { + var d = document.createElement('div'); + d.textContent = s; + return d.innerHTML; + } + + function loadCommits() { + if (!hasMore || loadingMore) return; + loadingMore = true; + loading.style.display = 'block'; + + var url = 'https://codeberg.org/api/v1/repos/emmett1/alicelinux/commits?limit=' + PER_PAGE + '&page=' + page; + + fetch(url) + .then(function (r) { + if (!r.ok) throw new Error('HTTP ' + r.status); + var link = r.headers.get('X-HasMore'); + if (link === 'false' || link === null) hasMore = false; + return r.json(); + }) + .then(function (data) { + if (!data.length || data.length < PER_PAGE) hasMore = false; + + data.forEach(function (c) { + var li = document.createElement('li'); + var hash = c.sha || ''; + var msg = c.commit.message.split('\n')[0] || ''; + var author = c.commit.author.name || 'unknown'; + var date = c.commit.author.date || ''; + var url = c.html_url || '#'; + + li.innerHTML = + '<span class="commit-hash"><a href="' + esc(url) + '">' + esc(fmtHash(hash)) + '</a></span>' + + '<span class="commit-msg"><a href="' + esc(url) + '">' + esc(msg) + '</a></span>' + + '<span class="commit-meta">' + esc(author) + '<br>' + esc(fmtDate(date)) + '</span>'; + list.appendChild(li); + }); + + page++; + loadingMore = false; + loading.style.display = 'none'; + }) + .catch(function (err) { + loadingMore = false; + loading.style.display = 'none'; + hasMore = false; + errEl.textContent = 'Failed to load commits: ' + err.message; + errEl.style.display = 'block'; + }); + } + + window.addEventListener('scroll', function () { + if (loadingMore || !hasMore) return; + var scrollBottom = window.scrollY + window.innerHeight; + var threshold = document.body.scrollHeight - 600; + if (scrollBottom >= threshold) loadCommits(); + }); + + loadCommits(); +}()); +</script> +EOF + cat files/footer + } > public/commits.html +} + +generate_commits_page + +generate_download_page() { + { + sed "s/@TITLE@/download/g" files/header + + listing=$(curl -sL --max-time 10 https://dl.alicelinux.org/ 2>/dev/null || true) + + cat << 'EOF' +<div id="dl-status" class="dl-empty">loading…</div> +<table class="dl-table" id="dl-table"><tbody> +EOF + + if [ -n "$listing" ]; then + echo "$listing" | sed -n '/<tbody>/,/<\/tbody>/p' | while IFS= read -r row; do + case $row in + *'<tr>'*) + href=$(printf '%s' "$row" | sed 's/.*<a href="\([^"]*\)">.*/\1/') + name=$(printf '%s' "$row" | sed 's/.*<a href="[^"]*">\([^<]*\)<.*/\1/') + size=$(printf '%s' "$row" | sed 's/.*<td class="s"[^>]*>\([^<]*\)<.*/\1/') + date=$(printf '%s' "$row" | sed 's/.*<td class="m">\([^<]*\)<.*/\1/') + type=$(printf '%s' "$row" | sed 's/.*<td class="t">\([^<]*\)<.*/\1/') + [ "$name" = "../" ] && continue + url="https://dl.alicelinux.org/$href" + if [ "$type" = "Directory" ]; then + printf '<tr><td><a href="%s">%s/</a></td><td>%s</td><td>%s</td></tr>\n' \ + "$(printf '%s' "$url" | html_escape)" \ + "$(printf '%s' "$name" | html_escape)" \ + "$(printf '%s' "$size" | html_escape)" \ + "$(printf '%s' "$date" | html_escape)" + else + printf '<tr><td><a href="%s">%s</a></td><td>%s</td><td>%s</td></tr>\n' \ + "$(printf '%s' "$url" | html_escape)" \ + "$(printf '%s' "$name" | html_escape)" \ + "$(printf '%s' "$size" | html_escape)" \ + "$(printf '%s' "$date" | html_escape)" + fi + ;; + esac + done + fi + + cat << 'EOF' +</tbody></table> +<script> +(function () { + var table = document.getElementById('dl-table'); + var tbody = table.querySelector('tbody'); + var status = document.getElementById('dl-status'); + + function esc(s) { + var d = document.createElement('div'); + d.textContent = s; + return d.innerHTML; + } + + function rowHTML(href, name, size, date, isDir) { + var url = 'https://dl.alicelinux.org/' + href; + var label = esc(name) + (isDir ? '/' : ''); + return '<tr><td><a href="' + esc(url) + '">' + label + '</a></td><td>' + esc(size) + '</td><td>' + esc(date) + '</td></tr>'; + } + + fetch('https://dl.alicelinux.org/') + .then(function (r) { + if (!r.ok) throw new Error('HTTP ' + r.status); + return r.text(); + }) + .then(function (html) { + var parser = new DOMParser(); + var doc = parser.parseFromString(html, 'text/html'); + var rows = doc.querySelectorAll('table tbody tr'); + var frag = document.createDocumentFragment(); + + rows.forEach(function (row) { + var cells = row.querySelectorAll('td'); + if (!cells.length) return; + var link = cells[0].querySelector('a'); + if (!link) return; + var href = link.getAttribute('href'); + var name = link.textContent; + if (name === '../') return; + var size = cells[2] ? cells[2].textContent.trim() : ''; + var date = cells[1] ? cells[1].textContent.trim() : ''; + var isDir = cells[3] && cells[3].textContent.trim() === 'Directory'; + var tr = document.createElement('tr'); + tr.innerHTML = rowHTML(href, name, size, date, isDir); + frag.appendChild(tr); + }); + + if (frag.childNodes.length) { + tbody.innerHTML = ''; + tbody.appendChild(frag); + } + status.textContent = ''; + status.style.display = 'none'; + }) + .catch(function () { + var rows = tbody.querySelectorAll('tr'); + if (rows.length) { + status.textContent = ''; + status.style.display = 'none'; + } else { + status.innerHTML = 'Unable to load. Visit <a href="https://dl.alicelinux.org">dl.alicelinux.org</a> directly.'; + } + }); +}()); +</script> +EOF + cat files/footer + } > public/download.html +} + +generate_download_page + # docs cat docs/readme.md > docs/index.md for f in docs/*.md; do diff --git a/files/footer b/files/footer index 42d9abbd..5b8c2af8 100644 --- a/files/footer +++ b/files/footer @@ -1,5 +1,5 @@ - <br><hr> - <p>Copyright (C) Alice Linux, 2024-2026</p> + <hr> + <p style="color: var(--fg-dim); font-size: 0.85em;">Copyright © Alice Linux, 2024-2026</p> </div> </body> </html> diff --git a/files/header b/files/header index 5faa51d9..bc0b5708 100644 --- a/files/header +++ b/files/header @@ -7,82 +7,174 @@ <style> :root { color-scheme: dark; - } + --bg: #0d0d0d; + --bg-alt: #141414; + --bg-code: #1a1a1a; + --fg: #e0e0e0; + --fg-dim: #888; + --accent: #a8a8a8; + --accent-hover: #e0e0e0; + --border: #222; + } + * { margin: 0; padding: 0; box-sizing: border-box; } body { - font-family: monospace; - font-size: 14px; - line-height: 1.25; - max-width: 92ch; - margin-left: auto; - margin-right: auto; - padding: 1em; - background-color: #242424; - color: #fefefe; - } - h1 { - margin: 0 0 0.35em; - font-size: 2rem; - line-height: 1.1; + font-family: "Terminus", "Monaco", "Cascadia Code", "Fira Code", "JetBrains Mono", "SF Mono", Consolas, monospace; + font-size: 15px; + line-height: 1.6; + max-width: 88ch; + margin: 0 auto; + padding: 2em 1.5em; + background: var(--bg); + color: var(--fg); + -webkit-font-smoothing: antialiased; + } + h1, h2, h3, h4 { font-weight: 600; line-height: 1.3; } + h1 { font-size: 1.75rem; margin-bottom: 0.6em; } + h2 { font-size: 1.3rem; margin: 1.6em 0 0.5em; } + h3 { font-size: 1.1rem; margin: 1.4em 0 0.4em; } + h4 { font-size: 1rem; margin: 1.2em 0 0.3em; } + p { margin: 0 0 1em; } + a { + color: var(--accent); + text-decoration: none; + } + a:hover { color: var(--accent-hover); text-decoration: underline; } + nav { margin-bottom: 1.5em; } + nav a { color: var(--fg-dim); font-size: 0.9em; } + nav a:hover { color: var(--accent); } + nav span { color: var(--border); margin: 0 0.3em; } + hr { + border: 0; + border-top: 1px solid var(--border); + margin: 1.5em 0; } - h2, h3, h4 { - line-height: 1.2; - margin-top: 1.4em; - margin-bottom: 0.5em; + pre, code { font-family: "SF Mono", "Cascadia Code", "Fira Code", "JetBrains Mono", Consolas, monospace; font-size: 0.9em; } + code { + background: var(--bg-code); + padding: 0.15em 0.4em; + border-radius: 3px; + color: #c0c0c0; } pre { - background-color: #2b2b2b; - border-radius: 3px; - padding: 10px; + background: var(--bg-code); + border: 1px solid var(--border); + border-radius: 4px; + padding: 1em; overflow-x: auto; + margin: 1em 0; + line-height: 1.45; } - code { - color: #f7f3d6; + pre code { + background: none; + padding: 0; + border-radius: 0; } img { display: block; max-width: 100%; + height: auto; + margin: 1em 0; + border-radius: 4px; } - hr { - border: 0; - border-top: 1px dashed #fefefe; - margin: 20px 0; + blockquote { + margin: 1em 0; + padding-left: 1em; + border-left: 3px solid var(--border); + color: var(--fg-dim); } table { width: 100%; border-collapse: collapse; - margin: 0.75rem 0; + margin: 1em 0; } th, td { - padding: 4px; - } - th { - background-color: #221e1f; + padding: 0.5em 0.6em; text-align: left; + border-bottom: 1px solid var(--border); } - table, th, td { - border: 1px dashed #e7e8eb; - } - table thead th { - border-bottom-color: #e7e8eb; - } - a { - color: #90cbf9; - text-decoration: none - } - a:hover { - color: #869edc; - text-decoration: underline - } - blockquote { - margin: 1rem 0; - padding-left: 1rem; - border-left: 2px solid rgba(254, 254, 254, 0.18); - color: #d0d0d0; + th { + font-weight: 600; + border-bottom-color: #333; + } + tr:last-child td { border-bottom: none; } + ul, ol { margin: 0 0 1em 1.5em; } + li { margin-bottom: 0.3em; } + input, button, textarea { font: inherit; color: inherit; } + .ports-toolbar { + display: flex; + flex-wrap: wrap; + gap: 0.5em; + margin-bottom: 1em; + } + .ports-toolbar button { + background: none; + border: none; + border-bottom: 2px solid transparent; + padding: 0.3em 0; + cursor: pointer; + color: var(--fg-dim); + font-size: 0.9em; + } + .ports-toolbar button.active { + color: var(--accent); + border-bottom-color: var(--accent); + } + .ports-toolbar button:hover { color: var(--fg); } + .ports-toolbar input { + flex: 1 1 18em; + min-width: 0; + background: var(--bg-alt); + border: 1px solid var(--border); + border-radius: 3px; + padding: 0.4em 0.6em; + } + .ports-toolbar input:focus { outline: none; border-color: var(--accent); } + .ports-count { margin-bottom: 0.8em; color: var(--fg-dim); font-size: 0.9em; } + #commits { list-style: none; margin: 0; } + #commits li { + padding: 0.8em 0; + border-bottom: 1px solid var(--border); + display: flex; + align-items: flex-start; + gap: 0.8em; + } + #commits li:last-child { border-bottom: none; } + .commit-hash { + font-family: "SF Mono", "Cascadia Code", "Fira Code", "JetBrains Mono", Consolas, monospace; + font-size: 0.8em; + color: var(--fg-dim); + white-space: nowrap; + min-width: 7em; + } + .commit-msg { flex: 1; word-break: break-word; } + .commit-meta { + font-size: 0.85em; + color: var(--fg-dim); + white-space: nowrap; + text-align: right; + min-width: 9em; + } + #commits-loading { + text-align: center; + padding: 1.5em; + color: var(--fg-dim); + display: none; + } + #commits-error { + text-align: center; + padding: 1em; + color: #e77; + display: none; } + .dl-table td:nth-child(1) { width: 60%; } + .dl-table td:nth-child(2) { width: 15%; text-align: right; } + .dl-table td:nth-child(3) { width: 25%; white-space: nowrap; } + .dl-empty { color: var(--fg-dim); font-style: italic; } </style> </head> <body> <div class="centered-wrapper"> - <h1>@TITLE@</h1> - <a href="/">home</a> / <a href="/docs">docs</a> / <a href="/ports.html">ports</a> / <a href="https://codeberg.org/emmett1/alicelinux">development</a> / <a href="https://sourceforge.net/projects/alice-linux/files/">download</a> / <a href="/community.html">community</a> / <a href="/donate.html">donate</a> + <nav> + <a href="/">home</a><span> / </span><a href="/docs">docs</a><span> / </span><a href="/ports.html">ports</a><span> / </span><a href="/commits.html">commits</a><span> / </span><a href="/download.html">download</a><span> / </span><a href="https://codeberg.org/emmett1/alicelinux">development</a><span> / </span><a href="/community.html">community</a><span> / </span><a href="/donate.html">donate</a> + </nav> <hr> @@ -1,4 +1,3 @@ -  **Alice Linux** is my personal daily driver minimal distro that used [Clang/LLVM](https://www.llvm.org/) as main C compiler, [musl](https://musl.libc.org/) as main standard libc library, [libressl](https://www.libressl.org) as main SSL/TLS and cryptographic libraries, [busybox](https://www.busybox.net/) as main core utilities, package manager written in POSIX shell script, [Wayland](https://wayland.freedesktop.org/) as the gui server and trying to be minimal, lightweight and usable as possible. |