From cefe57b980c593032ed587eaad73beb9992babf8 Mon Sep 17 00:00:00 2001 From: Thomas Eppers Date: Mon, 1 Nov 2021 13:07:11 +0100 Subject: [PATCH] first working version with ghcr --- src/repository/ghcr.rs | 75 ++++++++++++++++++++++++++++++++++++++++++ src/repository/mod.rs | 13 ++++---- 2 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 src/repository/ghcr.rs diff --git a/src/repository/ghcr.rs b/src/repository/ghcr.rs new file mode 100644 index 0000000..f46050c --- /dev/null +++ b/src/repository/ghcr.rs @@ -0,0 +1,75 @@ +use serde::Deserialize; + +use crate::repo; +use crate::repository::Error; + +#[derive(Deserialize)] +struct Token { + token: String, +} + +#[derive(Deserialize)] +pub struct Ghcr { + name: String, + tags: Vec, +} + +impl Ghcr { + /// fetches tag information with a repository name in the form of organization/repository or library/repository in the case of official images from docker + pub fn create_repo(repo: &str) -> Result { + let request_token = format!("https://ghcr.io/token?scope=repository:{}:pull", repo); + let response = match reqwest::blocking::get(request_token) { + Err(e) => return Err(Error::Fetching(format!("reqwest error: {}", e))), + Ok(response) => response, + }; + + let token = match response.json::() { + Err(e) => return Err(Error::Converting(format!("invalid token json: {}", e))), + Ok(token) => token.token, + }; + + let request = format!("https://ghcr.io/v2/{}/tags/list?n=100", repo); + let client = reqwest::blocking::Client::new(); + let response = match client + .get(request) + .header(reqwest::header::AUTHORIZATION, format!("Bearer {}", token)) + .send() + { + // let response = match reqwest::blocking::get(url) { + Ok(result) => result, + Err(e) => return Err(Error::Fetching(format!("reqwest error: {}", e))), + }; + + //convert it to json + let tags = match response.json::() { + Ok(result) => result, + Err(e) => return Err(Error::Converting(format!("invalid json: {}", e))), + }; + + if tags.tags.is_empty() { + return Err(Error::NoTagsFound); + } + + Ok(super::Repo { + tags: tags + .tags + .iter() + .map(|t| super::Tag { + name: t.clone(), + details: vec![], + last_updated: None, + }) + .collect(), + next_page: None, + }) + } +} + +#[cfg(test)] +mod tests { + use super::Ghcr; + #[test] + fn test_ghcr() { + Ghcr::create_repo("ghcr.io/linuxserver/beets").unwrap(); + } +} diff --git a/src/repository/mod.rs b/src/repository/mod.rs index ae45c6b..b1283f1 100644 --- a/src/repository/mod.rs +++ b/src/repository/mod.rs @@ -1,4 +1,5 @@ mod dockerhub; +mod ghcr; use std::fmt; @@ -99,13 +100,13 @@ impl Repo { }; //TODO change according to registry - // if ®istry == "ghcr.io" { - // // - // } else { - // dockerhub::DockerHub::new(repo) - // } + if registry.unwrap_or(String::new()) == "ghcr.io" { + ghcr::Ghcr::create_repo(&repo) + } else { + dockerhub::DockerHub::create_repo(&repo) + } - dockerhub::DockerHub::create_repo(&repo) + // dockerhub::DockerHub::create_repo(&repo) } pub fn with_url(url: &str) -> Result {