From 6e4a76586a34a8720342976a6819d0deb003f16f Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Wed, 29 May 2024 21:58:13 +0200 Subject: [PATCH 01/11] feat: improve website design --- .editorconfig | 2 +- resources/icon.opt.svg | 2 +- src/app.rs | 6 +- src/artifact_api.rs | 34 ++++-- src/templates.rs | 17 ++- templates/error.hbs | 66 ++++++----- templates/index.hbs | 139 +++++++++-------------- templates/listing.hbs | 242 +++++++++++++++++++++++++++------------- templates/selection.hbs | 198 +++++++++++++++++++++++++------- 9 files changed, 458 insertions(+), 248 deletions(-) diff --git a/.editorconfig b/.editorconfig index 7bffa7a..f72739e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,5 +10,5 @@ max_line_length = 88 [{Makefile,*.go}] indent_style = tab -[*.{json,md,rst,ini,yml,yaml,xml,html,js,jsx,ts,tsx,vue,svelte}] +[*.{json,md,rst,ini,yml,yaml,xml,html,js,jsx,ts,tsx,vue,svelte,hbs}] indent_size = 2 diff --git a/resources/icon.opt.svg b/resources/icon.opt.svg index 63d9a3e..d4d2a8b 100644 --- a/resources/icon.opt.svg +++ b/resources/icon.opt.svg @@ -1 +1 @@ - + diff --git a/src/app.rs b/src/app.rs index 27980bf..cbda200 100644 --- a/src/app.rs +++ b/src/app.rs @@ -29,7 +29,7 @@ use crate::{ error::{Error, Result}, gzip_reader::{PrecompressedGzipReader, GZIP_EXTRA_LEN}, query::Query, - templates::{self, LinkItem}, + templates::{self, ArtifactItem, LinkItem}, util::{self, InsertTypedHeader}, App, }; @@ -162,6 +162,7 @@ impl App { let tmpl = templates::Listing { main_url: state.i.cfg.main_url(), version: templates::Version, + run_url: &query.forge_url(), artifact_name: &artifact_name, path_components, n_dirs: listing.n_dirs, @@ -185,11 +186,12 @@ impl App { } let tmpl = templates::Selection { main_url: state.i.cfg.main_url(), + version: templates::Version, run_url: &query.forge_url(), run_name: &query.shortid(), artifacts: artifacts .into_iter() - .map(|a| LinkItem::from_artifact(a, &query, &state.i.cfg)) + .map(|a| ArtifactItem::from_artifact(a, &query, &state.i.cfg)) .collect(), }; Ok(Response::builder() diff --git a/src/artifact_api.rs b/src/artifact_api.rs index e49cafa..2207b49 100644 --- a/src/artifact_api.rs +++ b/src/artifact_api.rs @@ -23,7 +23,12 @@ pub struct Artifact { pub name: String, pub size: u64, pub expired: bool, + /// Artifact download URL used by the server pub download_url: String, + /// Artifact download URL shown to the user. If None, download_url is used + /// + /// GitHub uses different download URLs for their API and their frontend. + pub user_download_url: Option, } pub enum ArtifactOrRun { @@ -59,14 +64,18 @@ enum ForgejoArtifactStatus { Expired, } -impl From for Artifact { - fn from(value: GithubArtifact) -> Self { - Self { - id: value.id, - name: value.name, - size: value.size_in_bytes, - expired: value.expired, - download_url: value.archive_download_url, +impl GithubArtifact { + fn into_artifact(self, query: &Query) -> Artifact { + Artifact { + id: self.id, + name: self.name, + size: self.size_in_bytes, + expired: self.expired, + download_url: self.archive_download_url, + user_download_url: Some(format!( + "https://github.com/{}/{}/actions/runs/{}/artifacts/{}", + query.user, query.repo, query.run, self.id + )), } } } @@ -82,6 +91,7 @@ impl ForgejoArtifact { name: self.name, size: self.size, expired: matches!(self.status, ForgejoArtifactStatus::Expired), + user_download_url: None, } } } @@ -212,7 +222,11 @@ impl ArtifactApi { .json::>() .await?; - Ok(resp.artifacts.into_iter().map(Artifact::from).collect()) + Ok(resp + .artifacts + .into_iter() + .map(|a| a.into_artifact(query)) + .collect()) } async fn fetch_github(&self, query: &Query) -> Result { @@ -230,7 +244,7 @@ impl ArtifactApi { .error_for_status()? .json::() .await?; - Ok(ArtifactOrRun::Artifact(artifact.into())) + Ok(ArtifactOrRun::Artifact(artifact.into_artifact(query))) } None => Ok(ArtifactOrRun::Run(self.list_github(query).await?)), } diff --git a/src/templates.rs b/src/templates.rs index cde8110..5db4b9b 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -27,9 +27,10 @@ pub struct Error<'a> { #[template(path = "selection")] pub struct Selection<'a> { pub main_url: &'a str, + pub version: Version, pub run_url: &'a str, pub run_name: &'a str, - pub artifacts: Vec, + pub artifacts: Vec, } #[derive(Template)] @@ -37,6 +38,7 @@ pub struct Selection<'a> { pub struct Listing<'a> { pub main_url: &'a str, pub version: Version, + pub run_url: &'a str, pub artifact_name: &'a str, pub path_components: Vec, pub n_dirs: usize, @@ -50,11 +52,22 @@ pub struct LinkItem { pub url: String, } -impl LinkItem { +pub struct ArtifactItem { + pub name: String, + pub url: String, + pub size: u64, + pub expired: bool, + pub download_url: String, +} + +impl ArtifactItem { pub fn from_artifact(artifact: Artifact, query: &Query, cfg: &Config) -> Self { Self { name: artifact.name, url: cfg.url_with_subdomain(&query.subdomain_with_artifact(Some(artifact.id))), + size: artifact.size, + expired: artifact.expired, + download_url: artifact.user_download_url.unwrap_or(artifact.download_url), } } } diff --git a/templates/error.hbs b/templates/error.hbs index 63f7d40..6f5c8ed 100644 --- a/templates/error.hbs +++ b/templates/error.hbs @@ -1,40 +1,50 @@ - + Artifactview + -
- -

Error {{status}}

-

{{msg}}

+
+ +
+
+
+

Error {{status}}

+

{{msg}}

+
+ diff --git a/templates/index.hbs b/templates/index.hbs index 8cbf827..3a4a4a1 100644 --- a/templates/index.hbs +++ b/templates/index.hbs @@ -1,98 +1,65 @@ - Artifactview -
- -

Enter a GitHub/Gitea/Forgejo Actions run url to browse CI artifacts

-
- - -
- +
+ +
+
+
+

Enter a GitHub/Gitea/Forgejo Actions run url to browse CI artifacts

+
+ + +
+ +
diff --git a/templates/listing.hbs b/templates/listing.hbs index 85b9f10..635c9f6 100644 --- a/templates/listing.hbs +++ b/templates/listing.hbs @@ -1,82 +1,174 @@ - - - - - - -Index of {{artifact_name}} - - + + + + + + Index: + {{artifact_name}} + + - - + + -
- - - -

- {{#each path_components}}{{this.name}} /{{/each}} -

-
+
+ + + +

+ {{#each path_components}}{{this.name}} /{{/each}} +

+
+
+
+
+ {{n_dirs}} director{{#if n_dirs != 1}}ies{{else}}y{{/if}} + {{n_files}} file{{#if n_files != 1}}s{{/if}} + CI run + +
+
+
+ + + + + + + + + + {{#if has_parent}} + + + + + + {{/if}} + {{#each entries}} + + + + + + {{/each}} + +
Name  ↓ Size  ↓ CRC32
Parent directory
+ + + {{this.name}} + + {{#if this.is_dir}}—{{else}}{{this.size}}{{/if}}{{#if this.is_dir}}—{{else}}{{this.crc32}}{{/if}}
+
+
-
-
-
-{{n_dirs}} directories -{{n_files}} files - -
-
-
- - - - - - - - -{{#if has_parent}} - - - - - - -{{/if}} -{{#each entries}} - - - - - -{{/each}} - -
Name  ↓ Size  ↓ CRC32
Parent directory
- - - {{this.name}} - - {{#if this.is_dir}}—{{else}}{{this.size}}{{/if}}{{#if this.is_dir}}—{{else}}{{this.crc32}}{{/if}}
-
-
+ + - + + diff --git a/templates/selection.hbs b/templates/selection.hbs index be1b878..9a8918a 100644 --- a/templates/selection.hbs +++ b/templates/selection.hbs @@ -1,49 +1,161 @@ - - + - - - - Artifactview + + Artifacts: + {{run_name}} + - -
- - + + + + +
+ + -

CI artifacts for {{run_name}}:

- {{#each artifacts}} - {{this.name}} - {{/each}} -
+

+ {{run_name}} + / +

+ + +
+
+
+ {{artifacts.len()}} artifact{{#if artifacts.len() != 1}}s{{/if}} + CI run + +
+
+
+ + + + + + + + + + {{#each artifacts}} + + + + + + {{/each}} + +
ArtifactSizeDownload
+ + + {{this.name}} + + {{this.size}}Download
+
+
+ + + + From d267c824a4758a32ed356351ef7719727a543f15 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Wed, 29 May 2024 22:32:07 +0200 Subject: [PATCH 02/11] feat: add disclaimer --- src/app.rs | 4 ++++ src/templates.rs | 1 + templates/error.hbs | 6 +----- templates/index.hbs | 47 +++++++++++++++++++++++------------------ templates/selection.hbs | 11 +++++++++- 5 files changed, 43 insertions(+), 26 deletions(-) diff --git a/src/app.rs b/src/app.rs index cbda200..7c4e17a 100644 --- a/src/app.rs +++ b/src/app.rs @@ -189,6 +189,10 @@ impl App { version: templates::Version, run_url: &query.forge_url(), run_name: &query.shortid(), + publisher: LinkItem { + name: query.user.to_owned(), + url: format!("https://{}/{}", query.host, query.user), + }, artifacts: artifacts .into_iter() .map(|a| ArtifactItem::from_artifact(a, &query, &state.i.cfg)) diff --git a/src/templates.rs b/src/templates.rs index 5db4b9b..170c63e 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -30,6 +30,7 @@ pub struct Selection<'a> { pub version: Version, pub run_url: &'a str, pub run_name: &'a str, + pub publisher: LinkItem, pub artifacts: Vec, } diff --git a/templates/error.hbs b/templates/error.hbs index 6f5c8ed..2e42d4c 100644 --- a/templates/error.hbs +++ b/templates/error.hbs @@ -28,10 +28,7 @@ width="50" height="50" viewBox="0 0 13.229 13.229" - >
- diff --git a/templates/index.hbs b/templates/index.hbs index 3a4a4a1..94580f7 100644 --- a/templates/index.hbs +++ b/templates/index.hbs @@ -9,16 +9,16 @@ var(--color-text);} a { color: #006ed3; text-decoration: none; } a:hover { color: #319cff; } .card { display: flex; flex-direction: column; width: 90%; max-width: 500px; align-items: center; } .input-row { display: flex; width: 100%; } .center { - width: 100%; display: flex; flex-direction: row; justify-content: center; } input - { color: inherit; font-size: 16px; height: 32px; border: 1px solid - var(--color-border); padding: 4px 8px; } button { background-color: #006ed3; color: - #fff; padding: 4px 8px; border: none; cursor: pointer; } button:hover { opacity: - 0.7; } p { margin: 16px 0; } header { gap: 1em; padding-top: 10px; padding-bottom: - 10px; background-color: #f2f2f2; } footer { padding: 40px 20px; font-size: 12px; - text-align: center; } @media (prefers-color-scheme: dark) { * { --color-text: - #dddddd; --color-secondary: #082437; --color-border: #212121; } body { - background-color: #101010; } input {background-color: #151515;} header { - background-color: #151515; }} + width: 100%; display: flex; flex-direction: row; justify-content: center; } .light + { color: var(--color-text-light); } input { color: inherit; font-size: 16px; + height: 32px; border: 1px solid var(--color-border); padding: 4px 8px; } button { + background-color: #006ed3; color: #fff; padding: 4px 8px; border: none; cursor: + pointer; } button:hover { opacity: 0.7; } p { margin: 16px 0; } header { gap: 1em; + padding-top: 10px; padding-bottom: 10px; background-color: #f2f2f2; } footer { + padding: 40px 20px; font-size: 12px; text-align: center; } @media + (prefers-color-scheme: dark) { * { --color-text: #dddddd; --color-secondary: + #082437; --color-border: #212121; } body { background-color: #101010; } input + {background-color: #151515;} header { background-color: #151515; }} Artifactview @@ -49,17 +49,24 @@ /> -
+
+ + Artifactview + + {{version}} +

+ Disclaimer: + Artifactview does not host any websites, the data is fetched from the respective + software forge and is only stored temporarily on this server. The publisher of + the artifact is the only one responsible for the content. Most forges delete + artifacts after 90 days. +

+
diff --git a/templates/selection.hbs b/templates/selection.hbs index 9a8918a..c017a73 100644 --- a/templates/selection.hbs +++ b/templates/selection.hbs @@ -26,7 +26,8 @@ {text-align: right;padding-right: 20px;}#list td:nth-child(1) svg {position: absolute;}#list td .goup, #list td .name {margin-left: 1.75em;word-break: break-all;overflow-wrap: break-word;white-space: pre-wrap;}footer {padding: 40px - 20px;font-size: 12px;text-align: center;}@media (max-width: 600px) + 20px;font-size: 12px;text-align: center;}p { margin: 16px 0; }.light{ color: + var(--color-text-light); } @media (max-width: 600px) {td:nth-child(1) {width: auto;}td:nth-child(2), th:nth-child(2) {display: none;}h1 a {margin: 0;}#filter {max-width: 100px;}}@media (prefers-color-scheme: dark) {* {--color-secondary: #082437;--color-text: #dddddd;} @@ -141,6 +142,14 @@ rel="noopener noreferrer" >Artifactview {{version}} +

+ Disclaimer: Artifactview does not host any websites, the data is fetched + from the respective software forge and is only stored temporarily on this server. + The publisher of this artifact, + {{publisher.name}}, + is the only one responsible for the content. + Most forges delete artifacts after 90 days. +