Initial commit

This commit is contained in:
davidon-top 2023-09-30 11:08:59 +02:00
commit c15b95b325
5 changed files with 1657 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

1508
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

16
Cargo.toml Normal file
View file

@ -0,0 +1,16 @@
[package]
name = "sl"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = { version = "4.4.6", features = ["derive"] }
reqwest = { version = "0.11.20", features = ["json", "blocking"] }
serde = { version = "1.0.188", features = ["derive"] }
serde_json = "1.0.107"
tracing = "0.1.37"
tracing-subscriber = "0.3.17"
url = "2.4.1"
wl-clipboard-rs = "0.7.0"

26
LICENSE Normal file
View file

@ -0,0 +1,26 @@
GLWTS(Good Luck With That Shit) Public License
Copyright (c) Every-fucking-one, except the Author
Everyone is permitted to copy, distribute, modify, merge, sell, publish,
sublicense or whatever the fuck they want with this software but at their
OWN RISK.
Preamble
The author has absolutely no fucking clue what the code in this project
does. It might just fucking work or not, there is no third option.
GOOD LUCK WITH THAT SHIT PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION, AND MODIFICATION
0. You just DO WHATEVER THE FUCK YOU WANT TO as long as you NEVER LEAVE
A FUCKING TRACE TO TRACK THE AUTHOR of the original product to blame for
or held responsible.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Good luck and Godspeed.

106
src/main.rs Normal file
View file

@ -0,0 +1,106 @@
use std::io::Read;
use clap::{command, Parser};
use serde::{Deserialize, Serialize};
use url::Url;
use wl_clipboard_rs::paste::{get_contents, self};
pub static SHLINK_URL: &str = "https://l.davidon.top";
pub static SHLINK_API_KEY: &str = "26bef2a8-eda5-4660-91cc-2994a4bc2173";
pub static SHLINK_DOMAIN: &str = "l.davidon.top";
#[derive(Parser, Debug)]
#[command(author = "DavidOnTop", version = "0.1.0", about = "A cli tool to make short urls using shlink", long_about = None)]
struct Args {
/// number type
#[arg(short, long)]
max_visits: Option<u32>,
/// list type
#[arg(long)]
tags: Option<Vec<String>>,
/// string type
#[arg(long)]
title: Option<String>,
#[arg(short, long)]
crawlable: Option<bool>,
#[arg(short = 'q', long)]
forward_query: Option<bool>,
/// string type
#[arg(short = 's', long)]
custom_slug: Option<String>,
#[arg(short, long)]
find_if_exists: Option<bool>,
/// string type
#[arg(short, long)]
domain: Option<String>,
}
#[derive(Serialize, Debug)]
struct Req {
#[serde(rename = "longUrl")]
long_url: String,
#[serde(rename = "customSlug", skip_serializing_if = "Option::is_none")]
custom_slug: Option<String>,
#[serde(rename = "maxVisits", skip_serializing_if = "Option::is_none")]
max_visits: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
tags: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
title: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
crawlable: Option<bool>,
#[serde(rename = "forwardQuery")]
forward_query: bool,
#[serde(rename = "findIfExists")]
find_if_exists: bool,
domain: String,
}
#[derive(Deserialize, Debug)]
struct Res {
#[serde(rename = "shortUrl")]
short_url: String,
}
fn main() {
tracing_subscriber::fmt().with_max_level(tracing::Level::INFO).init();
let args = Args::parse();
tracing::info!("{:?}", args);
let clipboard_res = get_contents(paste::ClipboardType::Regular, paste::Seat::Unspecified, paste::MimeType::Text);
let clipboard = match clipboard_res {
Ok((mut pipe, _)) => {
let mut contents = String::new();
pipe.read_to_string(&mut contents).unwrap();
contents
},
Err(e) => panic!("Error: {}", e)
};
let clipboard = clipboard.split("\n").collect::<Vec<&str>>()[0].to_string();
tracing::info!("Clipboard: {}", clipboard);
let url = Url::parse(clipboard.as_str()).unwrap();
assert!(url.scheme() == "http" || url.scheme() == "https", "Clipboard does not contain a valid url");
assert!(url.host().is_some(), "Clipboard does not contain a valid url");
let req = Req {
long_url: clipboard,
custom_slug: args.custom_slug,
max_visits: args.max_visits,
tags: args.tags,
title: args.title,
crawlable: args.crawlable,
forward_query: args.forward_query.unwrap_or(true),
find_if_exists: args.find_if_exists.unwrap_or(true),
domain: args.domain.unwrap_or(SHLINK_DOMAIN.to_string()),
};
tracing::info!("Req: {:?}", serde_json::to_string(&req).unwrap());
let client = reqwest::blocking::Client::new();
let res: Res = client.post(format!("{}/rest/v3/short-urls", SHLINK_URL)).header("X-Api-Key", SHLINK_API_KEY).json(&req).send().unwrap().json().unwrap();
tracing::info!("Res: {:?}", res);
let cmd = format!("wl-copy {}", res.short_url);
tracing::info!("Cmd: {}", cmd);
std::process::Command::new("sh").arg("-c").arg(cmd).spawn().unwrap();
}