mirror of
https://github.com/SinTan1729/chhoto-url
synced 2025-04-20 11:50:01 -05:00
Compare commits
No commits in common. "a0f0eb5280babf806f95113f950ddb417079e37c" and "6659452c5196c2f1325971cdee45eb799321d327" have entirely different histories.
a0f0eb5280
...
6659452c51
6 changed files with 42 additions and 56 deletions
6
Makefile
6
Makefile
|
@ -13,11 +13,9 @@ build-dev:
|
||||||
docker-local: build-dev
|
docker-local: build-dev
|
||||||
docker build --tag chhoto-url --build-arg TARGETARCH=amd64 -f Dockerfile.multiarch .
|
docker build --tag chhoto-url --build-arg TARGETARCH=amd64 -f Dockerfile.multiarch .
|
||||||
|
|
||||||
docker-stop:
|
docker-test: docker-local
|
||||||
docker ps -q --filter "name=chhoto-url" | xargs -r docker stop
|
docker ps -q --filter "name=chhoto-url" | xargs -r docker stop
|
||||||
docker ps -aq --filter "name=chhoto-url" | xargs -r docker rm
|
docker ps -aq --filter "name=chhoto-url" | xargs -r docker rm
|
||||||
|
|
||||||
docker-test: docker-local docker-stop
|
|
||||||
docker run -p 4567:4567 --name chhoto-url -e password="${PASSWORD}" -d chhoto-url
|
docker run -p 4567:4567 --name chhoto-url -e password="${PASSWORD}" -d chhoto-url
|
||||||
docker logs chhoto-url -f
|
docker logs chhoto-url -f
|
||||||
|
|
||||||
|
@ -42,4 +40,4 @@ clean:
|
||||||
docker ps -aq --filter "name=chhoto-url" | xargs -r docker rm
|
docker ps -aq --filter "name=chhoto-url" | xargs -r docker rm
|
||||||
cargo clean --manifest-path=actix/Cargo.toml
|
cargo clean --manifest-path=actix/Cargo.toml
|
||||||
|
|
||||||
.PHONY: build-dev docker-local docker-stop build-release
|
.PHONY: build-dev docker-local build-release
|
||||||
|
|
4
actix/Cargo.lock
generated
4
actix/Cargo.lock
generated
|
@ -475,7 +475,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chhoto-url"
|
name = "chhoto-url"
|
||||||
version = "5.2.1"
|
version = "5.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-files",
|
"actix-files",
|
||||||
"actix-session",
|
"actix-session",
|
||||||
|
@ -485,8 +485,6 @@ dependencies = [
|
||||||
"rand",
|
"rand",
|
||||||
"regex",
|
"regex",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "chhoto-url"
|
name = "chhoto-url"
|
||||||
version = "5.2.1"
|
version = "5.2.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["Sayantan Santra <sayantan[dot]santra689[at]gmail[dot]com"]
|
authors = ["Sayantan Santra <sayantan[dot]santra689[at]gmail[dot]com"]
|
||||||
license = "mit"
|
license = "mit"
|
||||||
|
@ -32,5 +32,3 @@ rand = "0.8.5"
|
||||||
actix-session = { version = "0.9.0", features = ["cookie-session"] }
|
actix-session = { version = "0.9.0", features = ["cookie-session"] }
|
||||||
env_logger = "0.11.1"
|
env_logger = "0.11.1"
|
||||||
nanoid = "0.4.0"
|
nanoid = "0.4.0"
|
||||||
serde_json = "1.0.115"
|
|
||||||
serde = { version = "1.0.197", features = [ "derive" ] }
|
|
||||||
|
|
|
@ -1,12 +1,4 @@
|
||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
use serde::Serialize;
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
pub struct DBRow {
|
|
||||||
shortlink: String,
|
|
||||||
longlink: String,
|
|
||||||
hits: i64,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn find_url(shortlink: &str, db: &Connection) -> Option<String> {
|
pub fn find_url(shortlink: &str, db: &Connection) -> Option<String> {
|
||||||
let mut statement = db
|
let mut statement = db
|
||||||
|
@ -18,19 +10,17 @@ pub fn find_url(shortlink: &str, db: &Connection) -> Option<String> {
|
||||||
.ok()
|
.ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getall(db: &Connection) -> Vec<DBRow> {
|
pub fn getall(db: &Connection) -> Vec<String> {
|
||||||
let mut statement = db.prepare_cached("SELECT * FROM urls").unwrap();
|
let mut statement = db.prepare_cached("SELECT * FROM urls").unwrap();
|
||||||
|
|
||||||
let mut data = statement.query([]).unwrap();
|
let mut data = statement.query([]).unwrap();
|
||||||
|
|
||||||
let mut links: Vec<DBRow> = Vec::new();
|
let mut links: Vec<String> = Vec::new();
|
||||||
while let Some(row) = data.next().unwrap() {
|
while let Some(row) = data.next().unwrap() {
|
||||||
let row_struct = DBRow {
|
let short_url: String = row.get("short_url").unwrap();
|
||||||
shortlink: row.get("short_url").unwrap(),
|
let long_url: String = row.get("long_url").unwrap();
|
||||||
longlink: row.get("long_url").unwrap(),
|
let hits: i64 = row.get("hits").unwrap();
|
||||||
hits: row.get("hits").unwrap(),
|
links.push(format!("{short_url},{long_url},{hits}"));
|
||||||
};
|
|
||||||
links.push(row_struct);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
links
|
links
|
||||||
|
|
|
@ -5,13 +5,6 @@ use nanoid::nanoid;
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
struct URLPair {
|
|
||||||
shortlink: String,
|
|
||||||
longlink: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_longurl(shortlink: String, db: &Connection) -> Option<String> {
|
pub fn get_longurl(shortlink: String, db: &Connection) -> Option<String> {
|
||||||
if validate_link(&shortlink) {
|
if validate_link(&shortlink) {
|
||||||
|
@ -28,11 +21,12 @@ fn validate_link(link: &str) -> bool {
|
||||||
|
|
||||||
pub fn getall(db: &Connection) -> String {
|
pub fn getall(db: &Connection) -> String {
|
||||||
let links = database::getall(db);
|
let links = database::getall(db);
|
||||||
serde_json::to_string(&links).unwrap()
|
links.join("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_link(req: String, db: &Connection) -> (bool, String) {
|
pub fn add_link(req: String, db: &Connection) -> (bool, String) {
|
||||||
let mut chunks: URLPair = serde_json::from_str(&req).unwrap();
|
let chunks: Vec<&str> = req.split(';').collect();
|
||||||
|
let longlink = String::from(chunks[0]);
|
||||||
|
|
||||||
let style = env::var("slug_style").unwrap_or(String::from("Pair"));
|
let style = env::var("slug_style").unwrap_or(String::from("Pair"));
|
||||||
let len_str = env::var("slug_length").unwrap_or(String::from("8"));
|
let len_str = env::var("slug_length").unwrap_or(String::from("8"));
|
||||||
|
@ -41,16 +35,20 @@ pub fn add_link(req: String, db: &Connection) -> (bool, String) {
|
||||||
len = 4;
|
len = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if chunks.shortlink.is_empty() {
|
let mut shortlink;
|
||||||
chunks.shortlink = gen_link(style, len);
|
if chunks.len() > 1 {
|
||||||
|
shortlink = chunks[1].to_string().to_lowercase();
|
||||||
|
if shortlink.is_empty() {
|
||||||
|
shortlink = gen_link(style, len);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
shortlink = gen_link(style, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if validate_link(chunks.shortlink.as_str())
|
if validate_link(shortlink.as_str()) && get_longurl(shortlink.clone(), db).is_none() {
|
||||||
&& get_longurl(chunks.shortlink.clone(), db).is_none()
|
|
||||||
{
|
|
||||||
(
|
(
|
||||||
database::add_link(chunks.shortlink.clone(), chunks.longlink, db),
|
database::add_link(shortlink.clone(), longlink, db),
|
||||||
chunks.shortlink,
|
shortlink,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
(false, String::from("shortUrl not valid or already in use"))
|
(false, String::from("shortUrl not valid or already in use"))
|
||||||
|
|
|
@ -31,7 +31,16 @@ const refreshData = async () => {
|
||||||
document.getElementById("login-dialog").showModal();
|
document.getElementById("login-dialog").showModal();
|
||||||
document.getElementById("password").focus();
|
document.getElementById("password").focus();
|
||||||
} else {
|
} else {
|
||||||
data = JSON.parse(reply)
|
data = reply
|
||||||
|
.split("\n")
|
||||||
|
.filter(line => line !== "")
|
||||||
|
.map(line => line.split(","))
|
||||||
|
.map(arr => ({
|
||||||
|
short: arr[0],
|
||||||
|
long: arr[1],
|
||||||
|
hits: arr[2]
|
||||||
|
}));
|
||||||
|
|
||||||
displayData(data);
|
displayData(data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -78,18 +87,18 @@ const showAlert = async (text, col) => {
|
||||||
|
|
||||||
const TR = (row, site) => {
|
const TR = (row, site) => {
|
||||||
const tr = document.createElement("tr");
|
const tr = document.createElement("tr");
|
||||||
const longTD = TD(A_LONG(row["longlink"]), "Long URL");
|
const longTD = TD(A_LONG(row.long), "Long URL");
|
||||||
var shortTD = null;
|
var shortTD = null;
|
||||||
if (window.isSecureContext) {
|
if (window.isSecureContext) {
|
||||||
shortTD = TD(A_SHORT(row["shortlink"], site), "Short URL");
|
shortTD = TD(A_SHORT(row.short, site), "Short URL");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
shortTD = TD(A_SHORT_INSECURE(row["shortlink"], site), "Short URL");
|
shortTD = TD(A_SHORT_INSECURE(row.short, site), "Short URL");
|
||||||
}
|
}
|
||||||
hitsTD = TD(row["hits"]);
|
hitsTD = TD(row.hits);
|
||||||
hitsTD.setAttribute("label", "Hits");
|
hitsTD.setAttribute("label", "Hits");
|
||||||
hitsTD.setAttribute("name", "hitsColumn");
|
hitsTD.setAttribute("name", "hitsColumn");
|
||||||
const btn = deleteButton(row["shortlink"]);
|
const btn = deleteButton(row.short);
|
||||||
|
|
||||||
tr.appendChild(shortTD);
|
tr.appendChild(shortTD);
|
||||||
tr.appendChild(longTD);
|
tr.appendChild(longTD);
|
||||||
|
@ -159,19 +168,14 @@ const TD = (s, u) => {
|
||||||
|
|
||||||
const submitForm = () => {
|
const submitForm = () => {
|
||||||
const form = document.forms.namedItem("new-url-form");
|
const form = document.forms.namedItem("new-url-form");
|
||||||
const data ={
|
const longUrl = form.elements["longUrl"];
|
||||||
"longlink": form.elements["longUrl"].value,
|
const shortUrl = form.elements["shortUrl"];
|
||||||
"shortlink": form.elements["shortUrl"].value,
|
|
||||||
};
|
|
||||||
|
|
||||||
const url = prepSubdir("/api/new");
|
const url = prepSubdir("/api/new");
|
||||||
|
|
||||||
fetch(url, {
|
fetch(url, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
body: `${longUrl.value};${shortUrl.value}`
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify(data),
|
|
||||||
})
|
})
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
|
|
Loading…
Reference in a new issue