diff --git a/api.py b/api.py index 99d82f2..d28e3fb 100644 --- a/api.py +++ b/api.py @@ -16,8 +16,13 @@ async def root(): @app.get("/{url_id}", status_code=301, response_class=RedirectResponse) async def redirect_urls(url_id): - target_url = couch["urls"][url_id].get('full_url') - return RedirectResponse(target_url) + db = couch["urls"] + if url_id in db: + target_url = db[url_id].get('full_url') + return RedirectResponse(target_url) + else: + return RedirectResponse('static/404.html') + # TODO: Get JWT tokens working and use that to return only the user's urls # TODO: Look into how FastAPI handles the Authentication header diff --git a/api.restclient b/api.restclient index 298baf0..bd88b57 100644 --- a/api.restclient +++ b/api.restclient @@ -32,6 +32,10 @@ GET :host/eecd98 # Talk directly to CouchDB ### +# Get value from key +GET http://admin:password@127.0.0.1:5984/_all_dbs +:headers + # Get value from key GET http://admin:password@127.0.0.1:5984/urls/_all_docs?include_docs=true :headers diff --git a/project.todo b/project.todo index 28aa840..20c904c 100644 --- a/project.todo +++ b/project.todo @@ -2,10 +2,10 @@ #+TODO: TODO INPROGRESS | DONE BACKLOG #+STARTUP: overview -* TODO Move everything into an app directory -* TODO Knock out source code TODOs -* TODO Add button to copy shortened URL to clipboard -* TODO Add a 404 page in case the URL provided is invalid +* DONE Add button to copy shortened URL to clipboard +* DONE Add a 404 page in case the URL provided is invalid +* TODO RTFM on how to create docker compose files +* TODO Containerize couchdb * TODO Get the container running with the Dockerfile * TODO Point zipmy.link to joe-vps - [ ] Add DNS records @@ -14,8 +14,6 @@ * TODO Create a README.org * TODO Add MIT license -* BACKLOG Containerize couchdb -* BACKLOG RTFM on how to create docker compose files * BACKLOG RTFM on how to create a container network * BACKLOG Gitea Actions * BACKLOG Unit tests diff --git a/static/404.html b/static/404.html new file mode 100644 index 0000000..f93818d --- /dev/null +++ b/static/404.html @@ -0,0 +1,15 @@ + + +
+ + +The shortened URL you provided was not found. Sorry about that!
+ zipmy.link + + diff --git a/static/main.js b/static/main.js index 419f335..4c130cd 100644 --- a/static/main.js +++ b/static/main.js @@ -1,20 +1,33 @@ +function copyUrlToClipboard() { + const urlInput = document.getElementById("url-input"); + urlInput.select(); + urlInput.setSelectionRange(0, 99999); + navigator.clipboard.writeText(urlInput.value); +} + +function resetLinkGeneration() { +} + async function shortenUrl() { - const url = document.getElementById("url-input").value; - const btn = document.getElementById("submit-btn").value; + const urlInput = document.getElementById("url-input"); + const btn = document.getElementById("submit-btn"); // btn.enab const response = await fetch("/api/v1/urls", { method: 'PUT', headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ url: url, username: "anonymous" }) + body: JSON.stringify({ url: urlInput.value, username: "anonymous" }) }); const data = await response.json(); const resultElement = document.getElementById("result"); if (response.ok) { - resultElement.textContent = `Shortened Url: ${data.shortenedUrl}` - resultElement.style.color = "black"; + resultElement.textContent = '' + urlInput.value = data.shortenedUrl; + btn.innerText = "📋 Copy to Clipboard!"; + btn.onclick = copyUrlToClipboard; } else { resultElement.textContent = `Error: ${data.detail}` resultElement.style.color = "red"; + btn.value = "Shorten Url"; } }