Added option to delete a URL

This commit is contained in:
Przemek Dragańczuk 2020-02-16 16:52:54 +01:00
parent f47afab80b
commit 6d7b065e98
5 changed files with 62 additions and 6 deletions

View File

@ -36,6 +36,7 @@ public class App {
before("/*", authFilter); before("/*", authFilter);
get("/all", Routes::getAll); get("/all", Routes::getAll);
post("/new", Routes::addUrl); post("/new", Routes::addUrl);
delete("/:shortUrl", Routes::delete);
}); });
get("/:shortUrl", Routes::goToLongUrl); get("/:shortUrl", Routes::goToLongUrl);

View File

@ -54,4 +54,17 @@ public class Routes {
return ""; return "";
} }
public static String delete(Request req, Response res) {
String shortUrl = req.params("shortUrl");
var longUrlOpt = urlFile
.findForShortUrl(shortUrl);
if (longUrlOpt.isEmpty()) {
res.status(404);
return "";
}
urlFile.deleteEntry(String.format("%s,%s", shortUrl, longUrlOpt.get()));
return "";
}
} }

View File

@ -3,6 +3,7 @@ package tk.draganczuk.url;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption; import java.nio.file.StandardOpenOption;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -41,18 +42,41 @@ public class UrlFile {
public Optional<String> findForShortUrl(String shortUrl){ public Optional<String> findForShortUrl(String shortUrl){
try { try {
return Files.lines(file.toPath()) return Files.lines(file.toPath())
.map(this::splitLine) .map(this::splitLine)
.filter(pair -> pair.getLeft().equals(shortUrl)) .filter(pair -> pair.getLeft().equals(shortUrl))
.map(Pair::getRight) .map(Pair::getRight)
.findAny(); .findAny();
} catch (IOException e) { } catch (IOException e) {
return Optional.empty(); return Optional.empty();
} }
} }
public Pair<String, String> splitLine(String line){ public Pair<String, String> splitLine(String line) {
var split = line.split(","); var split = line.split(",");
return new Pair<>(split[0], split[1]); return new Pair<>(split[0], split[1]);
} }
public void deleteEntry(String entry) {
try {
File tmp = File.createTempFile(file.getName(), ".tmp");
if (!tmp.exists()) {
tmp.createNewFile();
}
Files.lines(file.toPath())
.filter(line -> !line.equals(entry))
.forEach(line -> {
try {
Files.writeString(tmp.toPath(), line + "\n", StandardOpenOption.APPEND);
} catch (IOException e) {
e.printStackTrace();
}
});
Files.move(tmp.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
e.printStackTrace();
}
}
} }

View File

@ -50,6 +50,7 @@
<tr> <tr>
<td>Long URL</td> <td>Long URL</td>
<td>Short url</td> <td>Short url</td>
<td></td>
</tr> </tr>
</thead> </thead>
<tbody id="url-table"> <tbody id="url-table">

View File

@ -23,9 +23,11 @@ const TR = (row) => {
const tr = document.createElement("tr"); const tr = document.createElement("tr");
const longTD = TD(A(row.long)); const longTD = TD(A(row.long));
const shortTD = TD(A_INT(row.short)); const shortTD = TD(A_INT(row.short));
const btn = deleteButton(row.short);
tr.appendChild(longTD); tr.appendChild(longTD);
tr.appendChild(shortTD); tr.appendChild(shortTD);
tr.appendChild(btn);
return tr; return tr;
}; };
@ -33,6 +35,21 @@ const TR = (row) => {
const A = (s) => `<a href='${s}'>${s}</a>`; const A = (s) => `<a href='${s}'>${s}</a>`;
const A_INT = (s) => `<a href='/${s}'>${window.location.host}/${s}</a>`; const A_INT = (s) => `<a href='/${s}'>${window.location.host}/${s}</a>`;
const deleteButton = (shortUrl) => {
const btn = document.createElement("button");
btn.innerHTML = "&times;";
btn.onclick = e => {
e.preventDefault();
fetch(`/api/${shortUrl}`, {
method: "DELETE"
}).then(_ => refreshData());
};
return btn;
};
const TD = (s) => { const TD = (s) => {
const td = document.createElement("td"); const td = document.createElement("td");
td.innerHTML = s; td.innerHTML = s;