en
This commit is contained in:
1 parent
cd64b9a14e
commit
feb9d91a3d
7 files changed
+88
-123
No files matched your search
+40
-45
@@ -5,10 +5,10 @@
|
||||
const el = (id) => document.getElementById(id);
|
||||
const CHANNEL_LABELS = {linux:'Linux',opnsense:'OPNsense',freebsd:'FreeBSD'};
|
||||
const INSTALL_NAMES = {deb:'Debian / Ubuntu',rpm:'RHEL / Rocky / Alma / Fedora',opnsense:'OPNsense',freebsd:'FreeBSD native'};
|
||||
const SECTION_LABELS = {overview:'Overview',packages:'Packages & versions',install:'Installation',repository:'Repositories'};
|
||||
const SECTION_LABELS = {overview:'Przegląd',packages:'Paczki i wersje',install:'Instalacja',repository:'Repozytoria'};
|
||||
const esc = (value) => String(value ?? '').replace(/[&<>"']/g, (char) => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[char]));
|
||||
const collator = new Intl.Collator('en', {numeric:true,sensitivity:'base'});
|
||||
const formatNumber = new Intl.NumberFormat('en-GB');
|
||||
const collator = new Intl.Collator('pl', {numeric:true,sensitivity:'base'});
|
||||
const formatNumber = new Intl.NumberFormat('pl-PL');
|
||||
const site = ['linux','opnsense','freebsd'].includes(document.body.dataset.site) ? document.body.dataset.site : 'linux';
|
||||
const state = {
|
||||
site, catalog:null, section:'overview', installing:site === 'linux' ? 'deb' : site,
|
||||
@@ -20,13 +20,13 @@
|
||||
if (!value) return '—';
|
||||
const time = new Date(value);
|
||||
if (Number.isNaN(time.valueOf())) return '—';
|
||||
return new Intl.DateTimeFormat('en-GB', {year:'numeric',month:'2-digit',day:'2-digit',hour:'2-digit',minute:'2-digit'}).format(time);
|
||||
return new Intl.DateTimeFormat('pl-PL', {year:'numeric',month:'2-digit',day:'2-digit',hour:'2-digit',minute:'2-digit'}).format(time);
|
||||
};
|
||||
const formatShortDate = (value) => {
|
||||
if (!value) return '—';
|
||||
const time = new Date(value);
|
||||
if (Number.isNaN(time.valueOf())) return '—';
|
||||
return new Intl.DateTimeFormat('en-GB', {day:'2-digit',month:'short',year:'numeric'}).format(time);
|
||||
return new Intl.DateTimeFormat('pl-PL', {day:'2-digit',month:'short',year:'numeric'}).format(time);
|
||||
};
|
||||
const formatSize = (value) => {
|
||||
const size = Number(value);
|
||||
@@ -43,7 +43,7 @@
|
||||
return '#';
|
||||
};
|
||||
const origin = (url) => typeof url === 'string' ? url.replace(/\/$/, '') : '';
|
||||
const dateLabel = (kind) => kind === 'build' ? 'Build timestamp recorded by the builder' : 'File modification time (older builds without a build timestamp)';
|
||||
const dateLabel = (kind) => kind === 'build' ? 'Data zapisana przez builder' : 'Data pliku (starsze buildy bez znacznika czasu)';
|
||||
const setText = (id, value) => {const node = el(id);if (node) node.textContent = value;};
|
||||
const versionText = (b) => b?.app_version ? `v${b.app_version}` : '—';
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
? `PKG · ${build?.opnsense_series || 'FreeBSD'}` : `PKG · ${build?.freebsd_abi || 'Native'}`;
|
||||
const version = build?.package_version || (live ? build?.app_version : '') || '—';
|
||||
return `<article class="build-card${live ? '' : ' off'}">
|
||||
<div class="build-card-top"><span>${esc(CHANNEL_LABELS[channel].toUpperCase())} / ${channel === 'linux' ? 'SIGNED' : 'PKG'}</span><span class="pill ${live ? 'live' : 'missing'}">${live ? 'PUBLISHED' : 'NOT BUILT'}</span></div>
|
||||
<div class="build-card-top"><span>${esc(CHANNEL_LABELS[channel].toUpperCase())} / ${channel === 'linux' ? 'SIGNED' : 'PKG'}</span><span class="pill ${live ? 'live' : 'missing'}">${live ? 'PUBLISHED' : 'BRAK BUILDU'}</span></div>
|
||||
<div class="build-card-version">${esc(version)}</div><div class="build-card-sub">${esc(subtitle)}</div>
|
||||
<div class="build-card-details"><div><small>BUILD DATE</small><strong title="${esc(dateLabel(build?.date_source))}">${esc(formatDate(build?.built_at))}</strong></div><div><small>COMMIT</small><strong class="commit">${esc(commit)}</strong></div></div>
|
||||
</article>`;
|
||||
@@ -92,7 +92,7 @@
|
||||
return `<span class="format-label${pkg.format === 'PKG' ? ' pkg' : ''}">${esc(pkg.format)}</span>`;
|
||||
}
|
||||
function tableRow(pkg, compact = false) {
|
||||
const download = `<a class="download-link" href="${esc(safeLink(pkg.download_url))}" target="_blank" rel="noopener noreferrer" download title="Download ${esc(pkg.name)} ${esc(pkg.version)}">${compact ? 'Download' : 'Download file'} <span>↗</span></a>`;
|
||||
const download = `<a class="download-link" href="${esc(safeLink(pkg.download_url))}" target="_blank" rel="noopener noreferrer" download title="Pobierz ${esc(pkg.name)} ${esc(pkg.version)}">${compact ? 'Pobierz' : 'Pobierz plik'} <span>↗</span></a>`;
|
||||
const first = `<span class="artifact-name" title="${esc(pkg.name)}">${esc(pkg.name)}</span><span class="artifact-arch">${esc(pkg.architecture)}</span>`;
|
||||
const format = `${formatBadge(pkg)}<span class="channel-tag ${pkg.format === 'PKG' ? 'pkg' : ''}">${esc(CHANNEL_LABELS[pkg.channel] || pkg.channel)}</span>`;
|
||||
const date = `<span class="date-cell" title="${esc(dateLabel(pkg.date_source))}">${esc(formatDate(pkg.built_at))}</span>`;
|
||||
@@ -112,29 +112,29 @@
|
||||
setText('stat-channels', `${data.summary?.channels_published || 0} / 3`);
|
||||
setText('stat-date', formatShortDate(data.summary?.latest_build_at));
|
||||
setText('stat-version', heroVersion);
|
||||
setText('stat-release', main?.package_version ? `Package: ${main.package_version}` : 'No release published yet');
|
||||
setText('stat-date-sub', 'Latest publication date');
|
||||
setText('stat-release', main?.package_version ? `Pakiet: ${main.package_version}` : 'Brak opublikowanej wersji');
|
||||
setText('stat-date-sub', 'Data ostatniej publikacji');
|
||||
setText('pipeline-updated', formatDate(data.generated_at));
|
||||
const ready = !!data.ready;
|
||||
el('hero-status').innerHTML = `<span class="pulse-dot"></span> ${ready ? 'REPOSITORY ONLINE' : 'WAITING FOR BUILD'}`;
|
||||
el('hero-status').innerHTML = `<span class="pulse-dot"></span> ${ready ? 'REPOZYTORIUM AKTYWNE' : 'OCZEKIWANIE NA BUILD'}`;
|
||||
el('hero-status').classList.toggle('waiting', !ready);
|
||||
el('sidebar-status').classList.toggle('waiting', !ready);
|
||||
el('sidebar-status').querySelector('span').textContent = ready ? 'REPOSITORY ONLINE' : 'WAITING FOR DATA';
|
||||
el('sidebar-status').querySelector('span').textContent = ready ? 'REPOSITORY ONLINE' : 'OCZEKIWANIE NA DANE';
|
||||
const side = el('side-channels');
|
||||
side.innerHTML = ['linux','opnsense','freebsd'].map((channel) => `<span class="side-channel${data.builds[channel]?.published ? '' : ' disabled'}"><i class="tiny-dot"></i>${esc(CHANNEL_LABELS[channel])}<small>${channel === 'linux' ? 'APT / DNF' : 'PKG'}</small></span>`).join('');
|
||||
el('build-grid').innerHTML = ['linux','opnsense','freebsd'].map((channel) => buildCard(data.builds[channel],channel)).join('');
|
||||
const recent = data.packages.filter((pkg) => state.site === 'linux' || pkg.channel === state.site).slice(0,6);
|
||||
el('recent-rows').innerHTML = recent.length ? recent.map((pkg) => tableRow(pkg,true)).join('') : '<tr><td colspan="5" class="empty-table">No packages published yet. The catalog will populate after the first build.</td></tr>';
|
||||
const recent = data.packages.slice(0,6);
|
||||
el('recent-rows').innerHTML = recent.length ? recent.map((pkg) => tableRow(pkg,true)).join('') : '<tr><td colspan="5" class="empty-table">Nie opublikowano jeszcze żadnych paczek. Katalog zapełni się po pierwszym buildzie.</td></tr>';
|
||||
}
|
||||
|
||||
function filteredPackages() {
|
||||
const arr = state.catalog?.packages || [];
|
||||
const search = state.search.trim().toLocaleLowerCase('en-GB');
|
||||
const search = state.search.trim().toLocaleLowerCase('pl-PL');
|
||||
const filtered = arr.filter((pkg) => {
|
||||
if (state.channel !== 'all' && pkg.channel !== state.channel) return false;
|
||||
if (state.format !== 'all' && pkg.format !== state.format) return false;
|
||||
if (!search) return true;
|
||||
return [pkg.name,pkg.version,pkg.channel,pkg.format,pkg.architecture].some((field) => String(field ?? '').toLocaleLowerCase('en-GB').includes(search));
|
||||
return [pkg.name,pkg.version,pkg.channel,pkg.format,pkg.architecture].some((field) => String(field ?? '').toLocaleLowerCase('pl-PL').includes(search));
|
||||
});
|
||||
if (state.sort === 'name') filtered.sort((a,b) => collator.compare(a.name,b.name) || collator.compare(b.version,a.version));
|
||||
if (state.sort === 'version') filtered.sort((a,b) => collator.compare(b.version,a.version) || collator.compare(a.name,b.name));
|
||||
@@ -147,10 +147,10 @@
|
||||
if (!data) return;
|
||||
const all = filteredPackages();
|
||||
const shown = all.slice(0,state.rows);
|
||||
setText('packages-total', `${formatNumber.format(data.summary.packages_count)} packages`);
|
||||
setText('filter-count', `${formatNumber.format(all.length)} ${all.length === 1 ? 'result' : 'results'}`);
|
||||
setText('result-range', all.length ? `Showing ${shown.length} of ${all.length}` : 'No matching packages');
|
||||
el('catalog-rows').innerHTML = shown.length ? shown.map((pkg) => tableRow(pkg)).join('') : '<tr><td colspan="6" class="empty-table">No packages match these filters. Adjust your search or check back after a new release.</td></tr>';
|
||||
setText('packages-total', `${formatNumber.format(data.summary.packages_count)} paczek`);
|
||||
setText('filter-count', `${formatNumber.format(all.length)} ${all.length === 1 ? 'wynik' : 'wyników'}`);
|
||||
setText('result-range', all.length ? `Wyświetlono ${shown.length} z ${all.length}` : 'Brak pasujących paczek');
|
||||
el('catalog-rows').innerHTML = shown.length ? shown.map((pkg) => tableRow(pkg)).join('') : '<tr><td colspan="6" class="empty-table">Brak paczek spełniających kryteria. Zmień filtry lub poczekaj na publikację.</td></tr>';
|
||||
el('show-more').hidden = shown.length >= all.length;
|
||||
}
|
||||
|
||||
@@ -163,9 +163,9 @@
|
||||
const component = data.apt_component || 'main';
|
||||
if (kind === 'deb') {
|
||||
return {
|
||||
description:'Add the signed APT repository, update the package list, and install RustProxy.',
|
||||
description:'Dodaj podpisane repozytorium APT, odśwież listę pakietów i zainstaluj RustProxy.',
|
||||
signature:'GPG SIGNED',
|
||||
note:'Supported: Debian / Ubuntu · amd64 architecture.',
|
||||
note:'Obsługiwane: Debian / Ubuntu · architektura amd64.',
|
||||
reference:`${linux}/apt/dists/${encodeURIComponent(distribution)}/InRelease`,
|
||||
agent:'sudo apt install rustproxy-docker-agent',
|
||||
code:[
|
||||
@@ -182,9 +182,9 @@
|
||||
}
|
||||
if (kind === 'rpm') {
|
||||
return {
|
||||
description:'Add the signed DNF/YUM repository and install the RustProxy server.',
|
||||
description:'Dodaj podpisane repozytorium DNF/YUM i zainstaluj serwer RustProxy.',
|
||||
signature:'GPG SIGNED',
|
||||
note:'Supported: RHEL / Rocky / Alma / Fedora · x86_64 architecture.',
|
||||
note:'Obsługiwane: RHEL / Rocky / Alma / Fedora · architektura x86_64.',
|
||||
reference:`${linux}/rpm/x86_64/repodata/repomd.xml`,
|
||||
agent:'sudo dnf install rustproxy-docker-agent',
|
||||
code:[
|
||||
@@ -206,11 +206,11 @@
|
||||
}
|
||||
if (kind === 'opnsense') {
|
||||
return {
|
||||
description:'Fetch the pkg repository configuration and install the os-rustproxy plugin.',
|
||||
description:'Pobierz konfigurację repozytorium pkg i zainstaluj plugin os-rustproxy.',
|
||||
signature:'UNSIGNED PKG',
|
||||
note:'The pkg repository index is unsigned. Only use a trusted HTTPS host.',
|
||||
note:'Repozytorium pkg nie ma podpisanego katalogu. Korzystaj tylko z zaufanego hosta HTTPS.',
|
||||
reference:`${opnsense}/RustProxy.conf`,
|
||||
agent:null,
|
||||
agent:'sudo apt install rustproxy-docker-agent',
|
||||
code:[
|
||||
'mkdir -p /usr/local/etc/pkg/repos',
|
||||
`fetch -o /usr/local/etc/pkg/repos/RustProxy.conf ${opnsense}/RustProxy.conf`,
|
||||
@@ -220,11 +220,11 @@
|
||||
};
|
||||
}
|
||||
return {
|
||||
description:'Install the native rustproxy package and enable its rc.d service.',
|
||||
description:'Zainstaluj natywny pakiet rustproxy i włącz usługę rc.d.',
|
||||
signature:'UNSIGNED PKG',
|
||||
note:'Requires FREEBSD_NATIVE_ENABLED=1. The pkg index is unsigned.',
|
||||
note:'Dostępne po ustawieniu FREEBSD_NATIVE_ENABLED=1. Katalog pkg jest niesygnowany.',
|
||||
reference:`${freebsd}/RustProxy-FreeBSD.conf`,
|
||||
agent:null,
|
||||
agent:'sudo dnf install rustproxy-docker-agent',
|
||||
code:[
|
||||
'mkdir -p /usr/local/etc/pkg/repos',
|
||||
`fetch -o /usr/local/etc/pkg/repos/RustProxy-FreeBSD.conf ${freebsd}/RustProxy-FreeBSD.conf`,
|
||||
@@ -251,12 +251,7 @@
|
||||
el('install-signature').classList.toggle('live', instructionsData.signature === 'GPG SIGNED');
|
||||
setText('install-command', instructionsData.code);
|
||||
setText('install-note', instructionsData.note);
|
||||
// Docker discovery agent is only built for Linux DEB/RPM.
|
||||
const hasDockerAgent = (kind === 'deb' || kind === 'rpm') && !!instructionsData.agent;
|
||||
el('agent-card').hidden = !hasDockerAgent;
|
||||
el('install-extra-grid').classList.toggle('single-card', !hasDockerAgent);
|
||||
setText('trust-index', hasDockerAgent ? '02' : '01');
|
||||
setText('agent-command', hasDockerAgent ? instructionsData.agent : '');
|
||||
setText('agent-command', instructionsData.agent);
|
||||
el('install-reference').href = safeLink(instructionsData.reference);
|
||||
}
|
||||
|
||||
@@ -274,7 +269,7 @@
|
||||
const distribution = encodeURIComponent(data.apt_distribution || 'stable');
|
||||
el('endpoints-grid').innerHTML = [
|
||||
endpointsCard('Linux','GPG SIGNED',url.linux,[
|
||||
{name:'GPG public key',url:`${url.linux}/repo-key.gpg`},
|
||||
{name:'Klucz publiczny GPG',url:`${url.linux}/repo-key.gpg`},
|
||||
{name:'APT InRelease',url:`${url.linux}/apt/dists/${distribution}/InRelease`},
|
||||
{name:'RPM repomd.xml',url:`${url.linux}/rpm/x86_64/repodata/repomd.xml`},
|
||||
{name:'Build info',url:`${url.linux}/LINUX-BUILD-INFO.txt`},
|
||||
@@ -295,13 +290,13 @@
|
||||
el('metadata-table').innerHTML = ['linux','opnsense','freebsd'].map((channel) => {
|
||||
const b = data.builds[channel] || {};
|
||||
const rows = [
|
||||
['APPLICATION VERSION',b.app_version || '—','latest-value'],
|
||||
['PACKAGE VERSION',b.package_version || '—',''],
|
||||
['BUILD DATE',formatDate(b.built_at),''],
|
||||
['WERSJA APLIKACJI',b.app_version || '—','latest-value'],
|
||||
['WERSJA PACZKI',b.package_version || '—',''],
|
||||
['DATA BUILDU',formatDate(b.built_at),''],
|
||||
['SOURCE COMMIT',b.source_commit || '—',''],
|
||||
['PACKAGING REVISION',b.packaging_revision || '—',''],
|
||||
['REWIZJA PAKOWANIA',b.packaging_revision || '—',''],
|
||||
];
|
||||
return `<div class="meta-block"><h3>${esc(CHANNEL_LABELS[channel])}</h3>${rows.map(([label,value,klass]) => `<div class="meta-row"><small>${esc(label)}</small><strong class="${klass}"${label === 'BUILD DATE' ? ` title="${esc(dateLabel(b.date_source))}"` : ''}>${esc(value)}</strong></div>`).join('')}</div>`;
|
||||
return `<div class="meta-block"><h3>${esc(CHANNEL_LABELS[channel])}</h3>${rows.map(([label,value,klass]) => `<div class="meta-row"><small>${esc(label)}</small><strong class="${klass}"${label === 'DATA BUILDU' ? ` title="${esc(dateLabel(b.date_source))}"` : ''}>${esc(value)}</strong></div>`).join('')}</div>`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
@@ -330,7 +325,7 @@
|
||||
el('error-banner').hidden = true;
|
||||
} catch (err) {
|
||||
el('error-banner').hidden = false;
|
||||
setText('last-sync','Load failed');
|
||||
setText('last-sync','Błąd odczytu');
|
||||
console.error('RustProxy repository:',err);
|
||||
} finally {
|
||||
state.refreshing = false;
|
||||
@@ -354,8 +349,8 @@
|
||||
input.remove();
|
||||
if (!copied) throw new Error('Clipboard unsupported');
|
||||
}
|
||||
toast('Copied to clipboard');
|
||||
} catch (_) { toast('Copy failed. Select and copy the command manually.'); }
|
||||
toast('Skopiowano do schowka');
|
||||
} catch (_) { toast('Nie udało się skopiować — zaznacz polecenia ręcznie'); }
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
Reference in new issue
Block a user