Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
hongquan committed Aug 8, 2021
0 parents commit 5698022
Show file tree
Hide file tree
Showing 7 changed files with 798 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Generated by Cargo
# will have compiled files and executables
/target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

.buildconfig
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
language: rust
rust:
- stable
cache: cargo
matrix:
fast_finish: true
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Changelog

## 0.1.0
* First version
23 changes: 23 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "duri"
version = "0.1.0"
authors = ["Nguyễn Hồng Quân <ng.hong.quan@gmail.com>"]
edition = "2018"
license = "GPL-3.0"
description = "CLI tool to get data URI of a file"
readme = "README.md"

[package.metadata.deb]
extended-description = """CLI tool to read a file and return its content as data URI.
It is useful when you want to upload file to a HTTP API, which requires data to be posted as JSON string.
You then can use this tool to get the file's base64-encoded content, passed to "jo" to build JSON string.
"""

[dependencies]
tree_magic_mini = "3.0.0"
clap = { version = "3.0.0-beta.2", features = [ "suggestions", "color" ] }
log = "0.4.14"
flexi_logger = { version = "0.18.0", features = ["colors"] }
color-eyre = "0.5.11"
base64 = "0.13.0"
urlencoding = "1.3.3"
674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Duri #

CLI tool to get data URI of a file

## Use case
74 changes: 74 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use std::path::Path;
use std::io::{stdin, Read};
use std::fs::File;
use std::str;

use log;
use base64;
use tree_magic_mini;
use urlencoding::encode as urlencode;
use color_eyre::eyre::{Result};
use clap::{crate_version, crate_authors, crate_description, Clap};
use flexi_logger::Logger;


#[derive(Clap)]
#[clap(version = crate_version!(), author = crate_authors!(), about = crate_description!())]
struct Opts {
#[clap(about = "Input file, pass \"-\" for standard input.")]
infile: String,
#[clap(short, long, about = "Prefer percent encoding for text file.")]
text: bool,
#[clap(short, long, parse(from_occurrences), about = "Verbosity level (repeat to increase).")]
verbose: i8,
}


fn read_input(infile: &str) -> Result<Vec<u8>> {
match infile {
"-" => {
let mut buf = Vec::<u8>::new();
let mut stdin = stdin();
stdin.read_to_end(&mut buf)?;
Ok(buf)
},
_ => {
let path = Path::new(infile);
let mut buf = Vec::<u8>::new();
File::open(path)?.read_to_end(&mut buf)?;
Ok(buf)
}
}
}


fn encode(content: Vec<u8>, mtype: &str, prefer_percent: bool) -> Result<String> {
let mut body = String::new();
if prefer_percent && mtype.starts_with("text/") {
body = urlencode(str::from_utf8(&content)?)
} else {
base64::encode_config_buf(&content, base64::URL_SAFE, &mut body)
}
Ok(body)
}


fn main() -> Result<()> {
let opts = Opts::parse();
let level = match opts.verbose {
0 => "warning",
1 => "info",
_ => "debug"
};
Logger::try_with_str(level)?.start()?;
log::debug!("Process file {}", opts.infile);
let infile = opts.infile.trim();
let content = read_input(infile)?;
let mtype = tree_magic_mini::from_u8(&content);
// Note: "content" is moved to encode() to be dropped early
let body = encode(content, mtype, opts.text)?;
log::info!("MIME type: {}", mtype);
let encoding = if opts.text && mtype.starts_with("text/") { "" } else { "base64" };
print!("data:{};{},{}", mtype, encoding, body);
Ok(())
}

0 comments on commit 5698022

Please sign in to comment.