feat: 1.0 release

This commit is contained in:
Elias Renman
2024-02-12 19:41:59 +01:00
commit d1b833f24c
8 changed files with 1489 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

1296
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

13
Cargo.toml Normal file
View File

@@ -0,0 +1,13 @@
[package]
name = "qr-code"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
arboard = {version = "3.3.0", features = ["wayland-data-control"]}
clap = { version = "4.0", features = ["derive"] }
image = "0.24.7"
qrcode = "0.13.0"
strum_macros = "0.25.3"

49
readme.md Normal file
View File

@@ -0,0 +1,49 @@
# QR Code CLI
A simple QR code generator for generating qr codes for urls.
## Prequsites
Note: On Linux, you may need to have xorg-dev and libxcb-composite0-dev to compile. On Debian and Ubuntu you can install them with
```Bash
sudo apt install xorg-dev libxcb-composite0-dev
```
## installing
Clone repository
```Bash
git clone https://github.com/eliasrenman/qr-cli.git && cd qr-cli
```
Build release
```Bash
cargo build --release
```
Linking release with temporary solution of manually adding a alias to the shell for the binary output.
### Specific instructions for ZSH
```Bash
echo "# QR Code CLI Link ">> ~/.zshrc &&
echo alias qr-code=\"$(pwd)/target/release/qr-code\" >> ~/.zshrc &&
source ~/.zshrc
```
### Specific instructions for Bash
```Bash
echo "# QR Code CLI Link ">> ~/.bashrc &&
echo alias qr-code=\"$(pwd)/target/release/qr-code\" >> ~/.bashrc &&
source ~/.bashrc
```
Verify installation by running
```Bash
qr-code
```

19
src/cli.rs Normal file
View File

@@ -0,0 +1,19 @@
use clap::Parser;
/// This is used to generate a QR Code png image which will be copied to the clipboard.
#[derive(Parser)]
pub struct QrUrl {
/// Url endpoint of the QR Code to be generated.
pub url: String,
// /// The output format of the QR Code.
// pub format: Format,
#[arg(hide(true), default_value(""))]
pub __internal_deamonize: String,
}
#[derive(clap::ValueEnum, Clone, strum_macros::Display)]
pub enum Format {
Svg,
Png,
Webp,
}

35
src/daemon.rs Normal file
View File

@@ -0,0 +1,35 @@
use std::{env, process};
pub struct Daemon {}
// An argument that can be passed into the program to signal that it should daemonize itself. This
// can be anything as long as it is unlikely to be passed in by the user by mistake.
pub const DAEMONIZE_ARG: &str = "__internal_daemonize";
impl Daemon {
pub fn in_daemon() -> bool {
let args: Vec<String> = std::env::args().collect();
return args.iter().any(|arg| arg == DAEMONIZE_ARG);
}
pub fn should_run_in_daemon() -> bool {
cfg!(target_os = "linux") && !Daemon::in_daemon()
}
pub fn run_in_daemon() {
let args: Vec<String> = std::env::args().collect();
let mut child_process = process::Command::new(env::current_exe().unwrap());
// Pass all the original arguments to the child process
for arg in args.iter().skip(1) {
child_process.arg(arg);
}
let _ = child_process
.arg(DAEMONIZE_ARG)
.stdin(process::Stdio::null())
.stdout(process::Stdio::null())
.stderr(process::Stdio::null())
.current_dir("/")
.spawn();
}
}

55
src/generate.rs Normal file
View File

@@ -0,0 +1,55 @@
use crate::daemon::Daemon;
#[cfg(target_os = "linux")]
use arboard::SetExtLinux;
use arboard::{Clipboard, ImageData};
use image::Rgba;
use qrcode::QrCode;
use std::borrow::Cow;
pub struct Generate {}
impl Generate {
// pub fn svg(url: String) {
// let code = QrCode::with_version(url, Version::Micro(2), EcLevel::L).unwrap();
// let image = code
// .render()
// .min_dimensions(200, 200)
// .dark_color(svg::Color("#000000"))
// .light_color(svg::Color("#ffffff"))
// .build();
// }
pub fn png(url: String) {
let code = QrCode::new(url).unwrap();
// Render the bits into an image.
let image = code
.render::<Rgba<u8>>()
.min_dimensions(200, 200)
.dark_color(Rgba([0, 0, 0, 255]))
.light_color(Rgba([255, 255, 255, 255]))
.build();
let image_data = ImageData {
width: usize::try_from(image.width()).unwrap(),
height: usize::try_from(image.height()).unwrap(),
bytes: Cow::from(image.into_vec()),
};
Generate::set_image(image_data);
}
fn set_image(image_data: ImageData<'_>) {
#[cfg(target_os = "linux")]
if Daemon::in_daemon() {
// print!("LINUX: Successfully copied png to clipboard\n");
let _ = Clipboard::new().unwrap().set().wait().image(image_data);
return;
}
let mut clipboard = Clipboard::new().unwrap();
let result = clipboard.set_image(image_data);
if result.is_err() {
println!("Failed copying png to clipboard");
println!("err: {:?}", result.unwrap_err().to_string());
} else {
println!("Successfully copied png to clipboard");
}
}
}

21
src/main.rs Normal file
View File

@@ -0,0 +1,21 @@
use crate::{cli::QrUrl, daemon::Daemon};
use clap::Parser;
mod cli;
mod daemon;
mod generate;
fn main() {
let qr_args = QrUrl::parse();
println!(
"url: {:?}, format: PNG",
qr_args.url,
// qr_args.format.to_string()
);
if Daemon::should_run_in_daemon() {
Daemon::run_in_daemon();
return;
}
generate::Generate::png(qr_args.url)
}