Skip to content

Commit

Permalink
Release v0.0.2
Browse files Browse the repository at this point in the history
Update all docstrings
Bump all dependency versions
Add doc specs and make crate a lib
  • Loading branch information
dormant-user committed Jul 29, 2024
1 parent 3647a4c commit 4526fb9
Show file tree
Hide file tree
Showing 9 changed files with 172 additions and 67 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/rust.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
id: set-release-flag
run: |
git pull
if git tag --list | grep "${{ env.pkg_version }}"; then
if git tag --list | grep "^${{ env.pkg_version }}$"; then
echo "Version ${{ env.pkg_version }} exists in tags, setting release flag to 'false'"
echo "release=false" >> $GITHUB_ENV
echo "release=false" >> "$GITHUB_OUTPUT"
Expand Down Expand Up @@ -191,7 +191,7 @@ jobs:
- release
- upload_assets
if: needs.release.outputs.release-flag == 'true'
runs-on: thevickypedia-lite
runs-on: thevickypedia-default
steps:
- uses: actions/checkout@v4
- name: Update Rust
Expand Down
27 changes: 19 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "lists3"
version = "0.0.1"
version = "0.0.2"
description = "Service that creates object listing functionality for S3 buckets"
edition = "2021"
authors = ["Vignesh Rao"]
Expand All @@ -14,15 +14,26 @@ categories = ["filesystem", "embedded", "development-tools", "visualization"]
include = ["/src", "LICENSE"]
exclude = [".github", ".gitignore", "README.md"]

[lib]
name = "lists3"
path = "src/lib.rs"

[[bin]]
name = "lists3"
path = "src/main.rs"

# Docs release queue
# https://docs.rs/releases/queue
# Verify docs locally
# cargo doc --no-deps --document-private-items --open
[package.metadata.docs.rs]
rustdoc-args = ["--document-private-items"]

[dependencies]
minijinja = { version = "2.0.1", features = ["loader"] }
url = "2.5.0"
serde = { version = "1.0.196", features = ["derive"] }
serde_json = "1.0.113"
aws-sdk-s3 = { version = "1", features = ["behavior-version-latest"] }
aws-config = { version = "1", features = ["behavior-version-latest"] }
tokio = { version = "1.37.0", features = ["full"] }
minijinja = { version = "2.1.0", features = ["loader"] }
url = "2.5.2"
serde = { version = "1.0.202", features = ["derive"] }
serde_json = "1.0.121"
aws-sdk-s3 = { version = "1.42.0", features = ["behavior-version-latest"] }
aws-config = { version = "1.5.4", features = ["behavior-version-latest"] }
tokio = { version = "1.39.2", features = ["full"] }
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# ListS3

[![made-with-rust][rust-logo]][rust-src-page]

[![crates.io][crates-logo]][crate]

[![build][gh-logo]][build]

#### Summary
[`lists3`][repo] is a self-hosted streaming engine, that can render media files via authenticated sessions.

# ListS3
File Browser for S3 buckets
[`lists3`][repo] is a light-weight CLI tool to create a file browser for S3 buckets provisioning bucket listing.

<details>
<summary><strong>Download pre-compiled OS specific executable</strong></summary>
Expand Down Expand Up @@ -79,6 +80,7 @@ cargo clippy --no-deps --fix

Licensed under the [MIT License][license]

[rust-src-page]: https://www.rust-lang.org/
[repo]: https://github.com/thevickypedia/lists3
[license]: https://github.com/thevickypedia/lists3/blob/main/LICENSE
[build]: https://github.com/thevickypedia/lists3/actions/workflows/rust.yaml
Expand Down
35 changes: 35 additions & 0 deletions src/aws.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ use aws_sdk_s3::types::Bucket;

use crate::squire;

/// Creates an AWS S3 client using the specified region.
///
/// # Arguments
///
/// * `region` - A reference to the AWS region to be used for the client.
///
/// # Returns
///
/// Returns an instance of `Client` configured for the specified region.
pub async fn get_client(
region: &Region
) -> Client {
Expand All @@ -18,6 +27,15 @@ pub async fn get_client(
Client::new(&config)
}

/// Determines the AWS region to be used based on the provided configuration.
///
/// # Arguments
///
/// * `config` - Configuration settings passed as flags or env vars.
///
/// # Returns
///
/// Returns an instance of `Region` based on the configuration or the default provider.
pub async fn get_region(
config: &squire::settings::Config
) -> Region {
Expand All @@ -31,6 +49,15 @@ pub async fn get_region(
}
}

/// Retrieves a list of all S3 buckets in the configured region.
///
/// # Arguments
///
/// * `client` - A reference to the AWS S3 client.
///
/// # Returns
///
/// Returns an `Option<Vec<Bucket>>` containing the list of buckets if successful.
pub async fn get_buckets(
client: &Client
) -> Option<Vec<Bucket>> {
Expand All @@ -43,6 +70,14 @@ pub async fn get_buckets(
}
}

/// Uploads an object to the specified S3 bucket.
///
/// # Arguments
///
/// * `client` - A reference to the AWS S3 client.
/// * `bucket_name` - The name of the bucket to upload the object to.
/// * `data` - The content of the object to be uploaded.
/// * `file_name` - The name of the object to be uploaded.
pub async fn upload_object(
client: &Client,
bucket_name: &String,
Expand Down
69 changes: 69 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#![allow(rustdoc::bare_urls)]
#![doc = include_str!("../README.md")]

use std;

use aws_config::Region;

mod templates;
mod squire;
mod aws;

/// Generates the HTML file required with template.
///
/// # Arguments
///
/// * `config` - Configuration settings passed as flags or env vars.
/// * `region` - Reference to the AWS region object.
/// * `metadata` - Project's metadata information stored as a struct.
///
/// # Returns
///
/// Returns a `String` response of the HTML page.
async fn generate_html(
config: &squire::settings::Config,
region: &Region,
metadata: &squire::constant::MetaData
) -> String {
let jinja = templates::environment();
let template_string = format!("list-s3-{}", config.style);
let list_object = jinja.get_template(template_string.as_str()).unwrap();
let html_data = list_object.render(minijinja::context!(
bucket_name => config.bucket,
region_name => region.to_string(),
folder_names => config.filter,
ignore_objects => config.ignore,
proxy_server => config.proxy.to_string(),
cargo_version => metadata.pkg_version
));
html_data.unwrap()
}

/// Initializes the application and uploads the generated HTML to S3.
pub async fn initiate() {
let metadata = squire::constant::build_info();
let config = squire::parser::arguments(&metadata);

let region = aws::get_region(&config).await;
let aws_client = aws::get_client(&region).await;

let mut bucket_names = Vec::new();
match aws::get_buckets(&aws_client).await {
Some(buckets) => {
for bucket in buckets {
bucket_names.push(bucket.name.unwrap());
}
}
None => {
eprintln!("Failed to fetch S3 buckets.");
std::process::exit(1)
}
}
if !bucket_names.contains(&config.bucket) {
eprintln!("\n{:?}\n\tBucket name is invalid.\n\tExpected one of {:?}\n",
&config.bucket, bucket_names);
std::process::exit(1)
}
let data = generate_html(&config, &region, &metadata).await;
aws::upload_object(&aws_client, &config.bucket, &data, &config.object).await;
}
53 changes: 1 addition & 52 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,55 +1,4 @@
use std::process::exit;

use aws_config::Region;

mod templates;
mod squire;
mod aws;

async fn generate_html(
config: &squire::settings::Config,
region: &Region,
metadata: &squire::constant::MetaData
) -> String {
let jinja = templates::environment();
let template_string = format!("list-s3-{}", config.style);
let list_object = jinja.get_template(template_string.as_str()).unwrap();
let html_data = list_object.render(minijinja::context!(
bucket_name => config.bucket,
region_name => region.to_string(),
folder_names => config.filter,
ignore_objects => config.ignore,
proxy_server => config.proxy.to_string(),
cargo_version => metadata.pkg_version
));
html_data.unwrap()
}

#[tokio::main]
async fn main() {
let metadata = squire::constant::build_info();
let config = squire::parser::arguments(&metadata);

let region = aws::get_region(&config).await;
let aws_client = aws::get_client(&region).await;

let mut bucket_names = Vec::new();
match aws::get_buckets(&aws_client).await {
Some(buckets) => {
for bucket in buckets {
bucket_names.push(bucket.name.unwrap());
}
}
None => {
eprintln!("Failed to fetch S3 buckets.");
exit(1)
}
}
if !bucket_names.contains(&config.bucket) {
eprintln!("\n{:?}\n\tBucket name is invalid.\n\tExpected one of {:?}\n",
&config.bucket, bucket_names);
exit(1)
}
let data = generate_html(&config, &region, &metadata).await;
aws::upload_object(&aws_client, &config.bucket, &data, &config.object).await;
lists3::initiate().await
}
31 changes: 30 additions & 1 deletion src/squire/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub struct Config {
///
/// # Panics
///
/// If the value is present, but it is an invalid data-type.
/// This function will print an error message and terminate the program if the value is present, but it is an invalid data-type.
fn parse_vec(value: &str) -> Option<Vec<String>> {
if value.is_empty() {
return None;
Expand All @@ -42,6 +42,15 @@ fn parse_vec(value: &str) -> Option<Vec<String>> {
}
}

/// Extracts the argument and parses it as a `Url`
///
/// # Returns
///
/// Returns a `Url` if the value is available.
///
/// # Panics
///
/// This function will print an error message and terminate the program if the value is not a valid URL.
fn parse_url(string: &str) -> Url {
if string.is_empty() {
return Url::parse("https://jarvis.vigneshrao.com/proxy").unwrap()
Expand All @@ -52,6 +61,26 @@ fn parse_url(string: &str) -> Url {
})
}

/// Parses the configuration for the application and returns a `Config` struct.
///
/// # Arguments
///
/// * `bucket` - The name of the S3 bucket. This is a mandatory field.
/// * `region` - The AWS region where the bucket is located.
/// * `filter` - A string representing filters to be applied, which will be parsed into a vector.
/// * `ignore` - A string representing patterns to be ignored, which will be parsed into a vector.
/// * `object` - The name of the object to be operated on.
/// * `proxy` - The proxy URL to be used, which will be parsed.
/// * `style` - The style option for the output. Expected values are "bootstrap" or "vanilla".
///
/// # Returns
///
/// Returns a `Config` struct populated with the parsed values.
///
/// # Panics
///
/// This function will print an error message and terminate the program if the `bucket` field is empty or if the `style`
/// option is invalid.
pub fn parse_config(
bucket: String,
region: String,
Expand Down
5 changes: 5 additions & 0 deletions src/templates/list_bootstrap.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/// Loads the HTML content for listing S3 contents with bootstrap template.
///
/// # Returns
///
/// Returns the HTML content as a `String`
pub fn get_content() -> String {
r###"<!DOCTYPE html>
<!--suppress JSUnresolvedLibraryURL, JSUnresolvedReference -->
Expand Down
5 changes: 5 additions & 0 deletions src/templates/list_vanilla.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/// Loads the HTML content for listing S3 contents with vanilla JS template.
///
/// # Returns
///
/// Returns the HTML content as a `String`
pub fn get_content() -> String {
r###"<!DOCTYPE html>
<!--suppress JSUnresolvedLibraryURL, JSUnresolvedReference -->
Expand Down

0 comments on commit 4526fb9

Please sign in to comment.