mirror of
https://github.com/minoplhy/chhoto-url.git
synced 2024-11-22 09:16:46 +00:00
add Edit function
This commit is contained in:
parent
201d0b319f
commit
abb48c68c5
@ -77,6 +77,15 @@ pub fn delete_link(shortlink: String, db: &Connection) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Edit Existing Long link.
|
||||||
|
pub fn edit_link(shortlink: String, longlink: String, db: &Connection) -> bool {
|
||||||
|
db.execute(
|
||||||
|
"UPDATE urls SET long_url = ?1 WHERE short_url = ?2;",
|
||||||
|
[longlink, shortlink],
|
||||||
|
)
|
||||||
|
.is_ok()
|
||||||
|
}
|
||||||
|
|
||||||
// Open the DB, and create schema if missing
|
// Open the DB, and create schema if missing
|
||||||
pub fn open_db(path: String) -> Connection {
|
pub fn open_db(path: String) -> Connection {
|
||||||
let db = Connection::open(path).expect("Unable to open database!");
|
let db = Connection::open(path).expect("Unable to open database!");
|
||||||
|
@ -63,6 +63,7 @@ async fn main() -> Result<()> {
|
|||||||
.service(services::siteurl)
|
.service(services::siteurl)
|
||||||
.service(services::version)
|
.service(services::version)
|
||||||
.service(services::add_link)
|
.service(services::add_link)
|
||||||
|
.service(services::edit_link)
|
||||||
.service(services::delete_link)
|
.service(services::delete_link)
|
||||||
.service(services::login)
|
.service(services::login)
|
||||||
.service(services::logout)
|
.service(services::logout)
|
||||||
|
@ -4,11 +4,7 @@
|
|||||||
use actix_files::NamedFile;
|
use actix_files::NamedFile;
|
||||||
use actix_session::Session;
|
use actix_session::Session;
|
||||||
use actix_web::{
|
use actix_web::{
|
||||||
delete, get,
|
delete, get, http::StatusCode, post, put, web::{self, Redirect}, Either, HttpResponse, Responder
|
||||||
http::StatusCode,
|
|
||||||
post,
|
|
||||||
web::{self, Redirect},
|
|
||||||
Either, HttpResponse, Responder,
|
|
||||||
};
|
};
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
@ -128,6 +124,26 @@ pub async fn logout(session: Session) -> HttpResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Edit link
|
||||||
|
#[put("/api/edit/{shortlink}")]
|
||||||
|
pub async fn edit_link(
|
||||||
|
req: String,
|
||||||
|
shortlink: web::Path<String>,
|
||||||
|
data: web::Data<AppState>,
|
||||||
|
session: Session,
|
||||||
|
) -> HttpResponse {
|
||||||
|
if env::var("public_mode") == Ok(String::from("Enable")) || auth::validate(session) {
|
||||||
|
let out = utils::edit_link(req, shortlink.to_string(), &data.db);
|
||||||
|
if out.0 {
|
||||||
|
HttpResponse::Created().body(out.1)
|
||||||
|
} else {
|
||||||
|
HttpResponse::Conflict().body(out.1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HttpResponse::Unauthorized().body("Not logged in!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Delete a given shortlink
|
// Delete a given shortlink
|
||||||
#[delete("/api/del/{shortlink}")]
|
#[delete("/api/del/{shortlink}")]
|
||||||
pub async fn delete_link(
|
pub async fn delete_link(
|
||||||
|
@ -17,6 +17,11 @@ struct URLPair {
|
|||||||
longlink: String,
|
longlink: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct EditLinkJson {
|
||||||
|
longlink: String,
|
||||||
|
}
|
||||||
|
|
||||||
// Request the DB for searching an URL
|
// Request the DB for searching an URL
|
||||||
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) {
|
||||||
@ -76,6 +81,46 @@ pub fn add_link(req: String, db: &Connection) -> (bool, String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make Check then edit the longurl link
|
||||||
|
pub fn edit_link(req: String, shortlink: String, db: &Connection) -> (bool, String) {
|
||||||
|
let chunks: EditLinkJson;
|
||||||
|
if let Ok(json) = serde_json::from_str(&req) {
|
||||||
|
chunks = json;
|
||||||
|
} else {
|
||||||
|
// shorturl should always be supplied, even if empty
|
||||||
|
return (false, String::from("Invalid request!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if shortlink.is_empty() {
|
||||||
|
(false, String::from("Invaild edit parameter received."));
|
||||||
|
}
|
||||||
|
|
||||||
|
if longurl_compares(shortlink.clone(), chunks.longlink.clone(), db)
|
||||||
|
{
|
||||||
|
(
|
||||||
|
database::edit_link(shortlink.clone(), chunks.longlink, db),
|
||||||
|
shortlink,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(
|
||||||
|
false,
|
||||||
|
String::from("Long/Short URL not valid or already in use!"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Doing Longurl check(Type None or existed?)
|
||||||
|
pub fn longurl_compares(shorturl: String, longurl:String, db: &Connection) -> bool {
|
||||||
|
if get_longurl(shorturl.clone(), db).is_none() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if get_longurl(shorturl.clone(), db).unwrap() == longurl {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if link, and request DB to delete it if exists
|
// Check if link, and request DB to delete it if exists
|
||||||
pub fn delete_link(shortlink: String, db: &Connection) -> bool {
|
pub fn delete_link(shortlink: String, db: &Connection) -> bool {
|
||||||
if validate_link(shortlink.as_str()) {
|
if validate_link(shortlink.as_str()) {
|
||||||
|
@ -56,6 +56,7 @@
|
|||||||
<td id="short-url-header">Short URL (click to copy)</td>
|
<td id="short-url-header">Short URL (click to copy)</td>
|
||||||
<td>Long URL</td>
|
<td>Long URL</td>
|
||||||
<td name="hitsColumn">Hits</td>
|
<td name="hitsColumn">Hits</td>
|
||||||
|
<td name="editBtn">Edit</td>
|
||||||
<td name="deleteBtn">×</td>
|
<td name="deleteBtn">×</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -105,19 +105,20 @@ const TR = (row, site) => {
|
|||||||
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["shortlink"], site), "Short URL");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
shortTD = TD(A_SHORT_INSECURE(row["shortlink"], site), "Short URL");
|
shortTD = TD(A_SHORT_INSECURE(row["shortlink"], site), "Short URL");
|
||||||
}
|
}
|
||||||
let hitsTD = TD(row["hits"]);
|
let 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 deleteBtn = deleteButton(row["shortlink"]);
|
||||||
|
const editBtn = editButton(row["shortlink"]);
|
||||||
|
|
||||||
tr.appendChild(shortTD);
|
tr.appendChild(shortTD);
|
||||||
tr.appendChild(longTD);
|
tr.appendChild(longTD);
|
||||||
tr.appendChild(hitsTD);
|
tr.appendChild(hitsTD);
|
||||||
tr.appendChild(btn);
|
tr.appendChild(editBtn);
|
||||||
|
tr.appendChild(deleteBtn);
|
||||||
|
|
||||||
return tr;
|
return tr;
|
||||||
}
|
}
|
||||||
@ -178,6 +179,53 @@ const deleteButton = (shortUrl) => {
|
|||||||
return td;
|
return td;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const editButton = (shortUrl) => {
|
||||||
|
const td = document.createElement("td");
|
||||||
|
const btn = document.createElement("button");
|
||||||
|
btn.innerHTML = "Edit";
|
||||||
|
|
||||||
|
btn.onclick = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const newUrl = prompt("Enter the new long URL:");
|
||||||
|
|
||||||
|
if (newUrl) {
|
||||||
|
if (!isValidUrl(newUrl)) {
|
||||||
|
showAlert("Invalid URL format. Please enter a valid URL.", "red");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch(prepSubdir(`/api/edit/${shortUrl}`), {
|
||||||
|
method: "PUT",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ longlink: newUrl }),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
showAlert(`Successfully updated ${shortUrl}.`, "green");
|
||||||
|
refreshData();
|
||||||
|
} else {
|
||||||
|
const errorMsg = await response.text();
|
||||||
|
showAlert(`Error: ${errorMsg}`, "red");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
td.setAttribute("name", "editBtn");
|
||||||
|
td.appendChild(btn);
|
||||||
|
return td;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isValidUrl = (urlString) => {
|
||||||
|
try {
|
||||||
|
new URL(urlString);
|
||||||
|
return true;
|
||||||
|
} catch (_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const TD = (s, u) => {
|
const TD = (s, u) => {
|
||||||
const td = document.createElement("td");
|
const td = document.createElement("td");
|
||||||
const div = document.createElement("div");
|
const div = document.createElement("div");
|
||||||
|
Loading…
Reference in New Issue
Block a user