mirror of
https://github.com/eliasrenman/qr-cli.git
synced 2026-03-16 20:46:07 +01:00
feat: 1.0 release
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
1296
Cargo.lock
generated
Normal file
1296
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
13
Cargo.toml
Normal file
13
Cargo.toml
Normal 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
49
readme.md
Normal 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
19
src/cli.rs
Normal 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
35
src/daemon.rs
Normal 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
55
src/generate.rs
Normal 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
21
src/main.rs
Normal 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)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user