mirror of
https://github.com/minoplhy/chhoto-url.git
synced 2024-12-22 11:57:55 +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
|
||||
pub fn open_db(path: String) -> Connection {
|
||||
let db = Connection::open(path).expect("Unable to open database!");
|
||||
|
@ -63,6 +63,7 @@ async fn main() -> Result<()> {
|
||||
.service(services::siteurl)
|
||||
.service(services::version)
|
||||
.service(services::add_link)
|
||||
.service(services::edit_link)
|
||||
.service(services::delete_link)
|
||||
.service(services::login)
|
||||
.service(services::logout)
|
||||
|
@ -4,11 +4,7 @@
|
||||
use actix_files::NamedFile;
|
||||
use actix_session::Session;
|
||||
use actix_web::{
|
||||
delete, get,
|
||||
http::StatusCode,
|
||||
post,
|
||||
web::{self, Redirect},
|
||||
Either, HttpResponse, Responder,
|
||||
delete, get, http::StatusCode, post, put, web::{self, Redirect}, Either, HttpResponse, Responder
|
||||
};
|
||||
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("/api/del/{shortlink}")]
|
||||
pub async fn delete_link(
|
||||
@ -144,4 +160,4 @@ pub async fn delete_link(
|
||||
} else {
|
||||
HttpResponse::Unauthorized().body("Not logged in!")
|
||||
}
|
||||
}
|
||||
}
|
@ -17,6 +17,11 @@ struct URLPair {
|
||||
longlink: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct EditLinkJson {
|
||||
longlink: String,
|
||||
}
|
||||
|
||||
// Request the DB for searching an URL
|
||||
pub fn get_longurl(shortlink: String, db: &Connection) -> Option<String> {
|
||||
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
|
||||
pub fn delete_link(shortlink: String, db: &Connection) -> bool {
|
||||
if validate_link(shortlink.as_str()) {
|
||||
|
@ -35,10 +35,10 @@
|
||||
<input type="url" name="longUrl" id="longUrl" placeholder="Please enter a valid URL"
|
||||
onblur="addProtocol(this)" required />
|
||||
</div>
|
||||
<div class=" pure-control-group">
|
||||
<div class="pure-control-group">
|
||||
<label for="shortUrl">Short URL (optional)</label>
|
||||
<input type="text" name="shortUrl" id="shortUrl" placeholder="Only a-z, 0-9, - and _ are allowed"
|
||||
pattern="[a-z0-9\-_]+" title="Only a-z, 0-9, - and _ are allowed"/>
|
||||
pattern="[a-z0-9\-_]+" title="Only a-z, 0-9, - and _ are allowed" />
|
||||
</div>
|
||||
<div class="pure-controls" id="controls">
|
||||
<button class="pure-button pure-button-primary">Shorten!</button>
|
||||
@ -56,6 +56,7 @@
|
||||
<td id="short-url-header">Short URL (click to copy)</td>
|
||||
<td>Long URL</td>
|
||||
<td name="hitsColumn">Hits</td>
|
||||
<td name="editBtn">Edit</td>
|
||||
<td name="deleteBtn">×</td>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -105,19 +105,20 @@ const TR = (row, site) => {
|
||||
var shortTD = null;
|
||||
if (window.isSecureContext) {
|
||||
shortTD = TD(A_SHORT(row["shortlink"], site), "Short URL");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
shortTD = TD(A_SHORT_INSECURE(row["shortlink"], site), "Short URL");
|
||||
}
|
||||
let hitsTD = TD(row["hits"]);
|
||||
hitsTD.setAttribute("label", "Hits");
|
||||
hitsTD.setAttribute("name", "hitsColumn");
|
||||
const btn = deleteButton(row["shortlink"]);
|
||||
const deleteBtn = deleteButton(row["shortlink"]);
|
||||
const editBtn = editButton(row["shortlink"]);
|
||||
|
||||
tr.appendChild(shortTD);
|
||||
tr.appendChild(longTD);
|
||||
tr.appendChild(hitsTD);
|
||||
tr.appendChild(btn);
|
||||
tr.appendChild(editBtn);
|
||||
tr.appendChild(deleteBtn);
|
||||
|
||||
return tr;
|
||||
}
|
||||
@ -178,6 +179,53 @@ const deleteButton = (shortUrl) => {
|
||||
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 = document.createElement("td");
|
||||
const div = document.createElement("div");
|
||||
|
Loading…
Reference in New Issue
Block a user